Spring Boot (+ RESTful)

Spring Boot - Maven/Gradle을 사용한 종속성 관리

wy-family 2024. 12. 16. 22:58

Maven과 Gradle은 프로젝트의 종속성(Dependency) 관리를 위해 주로 사용되는 빌드 도구입니다. 종속성은 라이브러리를 의미하며, 개발자가 프로젝트에서 필요로 하는 외부 코드, 즉 다른 개발자나 회사가 만들어 놓은 기능들을 가져와서 사용하는 것입니다. 

 

1. Maven을 사용한 종속성 관리

Maven은 XML 기반의 빌드 도구입니다. pom.xml 파일이 프로젝트의 중심입니다.

주요 개념

  1. pom.xml 파일: Maven 프로젝트의 설정 파일입니다. 프로젝트의 종속성, 플러그인, 빌드 설정 등을 정의합니다.
  2. 의존성(Dependency): 외부 라이브러리의 선언입니다. Maven은 선언된 라이브러리를 중앙 리포지토리에서 다운로드합니다.
  3. 중앙 리포지토리(Central Repository): Maven이 사용할 수 있는 라이브러리의 저장소입니다. 기본적으로 Maven은 인터넷에 존재하는 중앙 리포지토리에서 라이브러리를 가져옵니다.

2. Gradle을 사용한 종속성 관리

Gradle은 Maven보다 유연하고 성능이 좋은 빌드 도구입니다. Gradle은 Groovy 또는 Kotlin DSL을 사용해 설정합니다.

주요 개념

  1. build.gradle: Gradle 프로젝트의 설정 파일입니다. 종속성과 빌드 설정을 정의합니다.
  2. 의존성 관리: dependencies { ... } 블록을 통해 종속성을 추가합니다.
  3. 리포지토리: Maven과 마찬가지로 중앙 저장소에서 라이브러리를 가져옵니다.

오른쪽에 있는 것들은 라이브러리 이름이니까 라이브러리는 mvnRepository.com (중앙 레포지토리) 에서 검색을 해오면 된다. 거기서 쓰는 표기법은 가지고 올 수 있다.


앞에 붙어있는 수식어들, implementation, compileOnly, developmentOnly, runtimeOnly, annotationProcessor, testImplementation, testRuntimeOnly 은 뭘까?

 

앞에 붙어 있는 **implementation, compileOnly, developmentOnly, runtimeOnly, annotationProcessor, testImplementation, testRuntimeOnly**와 같은 키워드들은 Gradle에서 **의존성의 범위(Scope)**를 정의하는 수식어들입니다.
Gradle은 Maven의 scope 개념을 확장한 것으로, 더 세분화된 범위를 제공합니다.


1. implementation

  • 설명: 컴파일 및 런타임에 모두 필요한 종속성을 추가합니다.
  • 특징:
    • 다른 모듈에서 이 종속성은 노출되지 않습니다. (캡슐화)
    • 모듈 경계를 유지하면서 종속성을 더 효율적으로 관리할 수 있습니다.

2. compileOnly

  • 설명: 컴파일할 때만 필요한 종속성을 추가합니다. 런타임 시에는 포함되지 않습니다.
  • 특징:
    • 예를 들어, Lombok과 같이 컴파일 시에만 필요한 라이브러리에 사용됩니다.
    • 런타임에 실제 코드로 변환되므로 따로 필요하지 않습니다.

3. runtimeOnly

  • 설명: 런타임에만 필요한 종속성을 추가합니다. 컴파일 시에는 포함되지 않습니다.
  • 특징:
    • 예를 들어, H2 데이터베이스와 같이 런타임에서 실행되는 환경에서만 필요한 경우 사용됩니다.
    • 컴파일 시에는 이 라이브러리가 필요하지 않기 때문에 메모리와 빌드 시간을 절약할 수 있습니다.

4. developmentOnly

  • 설명: 개발 중에만 필요한 종속성입니다.
  • 특징:
    • 개발 환경에서만 사용되는 라이브러리입니다.
    • 예를 들어, Spring Boot DevTools는 개발 시 코드 변경을 감지하고 애플리케이션을 자동 재시작하는 기능을 제공합니다.

5. annotationProcessor

  • 설명: 어노테이션 기반 코드 생성 및 처리를 위한 종속성입니다.
  • 특징:
    • 어노테이션을 컴파일러가 처리하는 단계에서 사용됩니다.
    • Lombok과 같은 라이브러리의 경우 getter, setter 등의 코드를 자동으로 생성합니다.

6. testImplementation

  • 설명: 테스트 코드에서만 사용할 종속성을 추가합니다.
  • 특징:
    • 테스트 환경에서만 사용되는 라이브러리입니다.
    • JUnit, Mockito 등의 테스트 도구를 선언할 때 사용합니다.

7. testRuntimeOnly

  • 설명: 테스트 실행 시에만 필요한 종속성을 추가합니다.
  • 특징:
    • 테스트 시 런타임에만 필요한 라이브러리입니다.
    • 예를 들어, JUnit 플랫폼의 런처는 테스트 실행 시에만 필요합니다.

Gradle 의존성 스코프 요약

키워드 컴파일 단계 런타임 단계 다른 모듈에 노출 여부 용도 및 특징
implementation O O X 일반적으로 많이 사용됨, 캡슐화됨
compileOnly O X X 컴파일 시에만 필요함 (예: Lombok)
runtimeOnly X O X 런타임에만 필요함 (예: H2 데이터베이스)
developmentOnly X O X 개발 중에만 필요함 (예: DevTools)
annotationProcessor 컴파일러 단계 X X 어노테이션 기반 코드 생성
testImplementation O O (테스트) X 테스트 코드에만 필요함
testRuntimeOnly X O (테스트) X 테스트 실행 시에만 필요함

결론

이처럼 Gradle에서 사용되는 각 키워드라이브러리의 사용 범위와 목적을 명확하게 설정해 줍니다.

  • **implementation**은 기본적으로 많이 사용되며, 코드의 모듈화를 유지하면서 종속성을 추가합니다.
  • compileOnly, runtimeOnly 등을 사용하면 필요한 범위에만 라이브러리를 포함시켜 성능을 최적화할 수 있습니다.

이런 스코프를 이해하면 프로젝트 빌드를 효율적으로 관리할 수 있습니다!


 

test 의 경우는 애자일 방법론과 연관이 있다.

애자일 방법론이란 무엇인가?

애자일(Agile) 방법론은 소프트웨어 개발에서 유연하고 빠르게 변화에 대응하며 개발하는 방법론입니다.
기존의 워터폴(Waterfall) 모델처럼 프로젝트의 전체 계획을 처음부터 끝까지 확정하고 개발하는 대신,
애자일은 **짧은 주기(Iteration)**로 프로젝트를 나누고 지속적으로 개선하며 완성도를 높입니다.


애자일의 핵심 원칙

애자일 방법론은 **애자일 선언문(Agile Manifesto)**의 4가지 핵심 가치를 기반으로 합니다:

  1. 프로세스와 도구보다는 사람과 상호작용을 중시
  2. 방대한 문서보다는 작동하는 소프트웨어를 우선
  3. 계획을 따르기보다는 변화에 유연하게 대응
  4. 계약 협상보다는 고객과의 협력을 중요시

결국, 애자일은 빠르게 작은 결과물을 만들고 지속적인 피드백을 통해 더 나은 제품을 만드는 것을 목표로 합니다.


Gradle 종속성과 애자일의 연결

Gradle과 같은 빌드 도구 및 종속성 관리가 애자일 개발과 어떻게 연결되는지 설명해보겠습니다.

1. 지속적 통합과 배포 (CI/CD)

애자일에서는 **지속적 통합(Continuous Integration)**과 **지속적 배포(Continuous Delivery)**를 강조합니다.

  • Gradle의 빠른 빌드의존성 관리는 개발 주기마다 작은 단위의 코드를 빌드하고 배포하는 데 도움을 줍니다.
  • 예를 들어, implementation과 같은 범위를 통해 필요한 라이브러리만 포함시켜 빌드 시간을 단축합니다.

적용 예시:
애자일 스프린트가 끝나면 빠르게 배포 가능한 코드를 준비합니다. gradle build와 같은 명령으로 빌드 및 테스트를 실행하고,
의존성 트리(gradle dependencies)를 통해 불필요한 라이브러리를 제거하여 품질을 높입니다.


2. 테스트 우선 개발 (Test-Driven Development, TDD)

애자일에서는 **테스트 우선 개발(TDD)**을 자주 사용합니다.

  • Gradle에서 제공하는 **testImplementation**과 **testRuntimeOnly**는 테스트를 빠르게 실행하고 관리하는 데 매우 유용합니다.
  • 단위 테스트통합 테스트를 나누어 라이브러리 범위를 설정함으로써 테스트 코드와 애플리케이션 코드의 경계를 명확히 합니다.

적용 예시:

dependencies {
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
  • 테스트 의존성은 testImplementation에 추가하고, 런타임에만 필요한 것은 testRuntimeOnly로 분리합니다.
  • 이처럼 테스트 관련 라이브러리를 명확히 분리하면 테스트 속도품질을 동시에 확보할 수 있습니다.

3. 점진적 개발 및 리팩토링

애자일 개발은 작은 단위의 기능을 반복적으로 개발하고 **리팩토링(Refactoring)**을 통해 개선합니다.
Gradle의 유연한 의존성 스코프는 개발 중 특정 라이브러리를 빠르게 교체하거나 업데이트할 수 있도록 도와줍니다.

적용 예시:

  • 개발 시에는 developmentOnly를 사용해 DevTools를 포함하고, 배포 시에는 불필요한 라이브러리를 제거합니다.
dependencies {
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
}
  • 이렇게 하면 개발 환경에서는 자동 재시작 기능을 사용하고, 배포 환경에서는 성능을 최적화합니다.

4. 작동하는 소프트웨어의 지속적 제공

애자일에서는 짧은 스프린트마다 작동하는 소프트웨어를 고객에게 제공합니다. Gradle은 이를 위한 빠른 빌드와 테스트를 지원합니다.

  • 종속성 범위를 명확히 설정해 불필요한 코드 실행을 막고, 필요한 의존성만 포함시켜 소프트웨어 품질을 높입니다.

적용 예시:

  • 런타임에만 필요한 종속성은 runtimeOnly로 선언하고, 불필요한 종속성을 배포 파일에서 제거합니다.

애자일과 Gradle: 결론

Gradle의 의존성 범위(implementation, testImplementation, runtimeOnly 등)를 활용하면,
애자일 방법론의 지속적 통합, 반복적 개발, 테스트 우선 개발 원칙을 더욱 효과적으로 실현할 수 있습니다.

핵심 포인트:

  • Gradle은 빠른 빌드 및 테스트를 통해 짧은 주기의 개발을 지원합니다.
  • 의존성 스코프를 명확히 설정함으로써 코드 품질과 배포 성능을 최적화합니다.
  • 애자일의 핵심 가치인 변화에 유연하게 대응하는 환경을 만들어줍니다.

Gradle 의 dependencies 에서 종속성 관리를 한다.

이것들은 spring initializr 에서 만들때 자동으로 채워져 있지만, 별도로 필요한 것이 있으면 mvnrepository.com 에서 찾아서 추가하면 되겠다.