Gradle에 대해 알아보자 #3 - 의존성 관리

햄햄·2023년 2월 26일
0

Gradle

목록 보기
3/3

의존성 관리란?

의존성이란 내 프로젝트에서 사용하고 있는 라이브러리, 패키지 등을 의미한다. 의존성 관리를 통해 의존성을 자동화된 방식으로 선언하고, 해결하고, 사용할 수 있다.

Gradle에서의 의존성 관리

프로젝트 코드가 빌드될 때 의존성 모듈도 함께 빌드될 수 있도록 Gradle에 해당 모듈을 찾을 수 있는 위치를 알려주어야 한다. 여기서 모듈을 저장하는 위치를 리포지토리라고 한다. 빌드에 대한 리포지토리를 선언하면 Gradle은 모듈을 찾고 검색한다. 리포지토리는 로컬 디렉토리 또는 원격 리포지토리 등 다양한 형태로 제공될 수 있다.

런타임에 Gradle은 선언된 의존성 찾고, 원격 저장소에서 다운로드하거나 로컬 디렉토리에서 검색하거나 멀티 프로젝트 설정에서 다른 프로젝트를 빌드할 수도 있습니다. 이 프로세스를 의존성 해결(dependency resolution)이라고 한다.

의존성이 해결(resolution)되면 해결(resolution) 메커니즘은 의존성의 기본 파일을 의존성 캐시라고도 하는 로컬 캐시에 저장한다. 향후 빌드에서는 불필요한 네트워크 호출을 피하기 위해 캐시에 저장된 파일을 재사용한다.

모듈은 추가 메타데이터를 제공할 수 있다. 메타데이터는 리포지토리에서 모듈을 찾기 위한 좌표, 프로젝트 또는 작성자에 대한 정보 등 모듈을 더 자세히 설명하는 데이터이다. 메타데이터에는 모듈이 제대로 작동하기 위해 다른 모듈이 필요하다는 것을 정의할 수 있다. Gradle은 전이 의존성이라고 하는 이러한 추가 모듈을 자동으로 해결(resolve)한다.

의존성 선언

의존성 선언을 보기 전에 의존성 구성(dependency configuration)에 대한 개념을 정의할 필요가 있다.

의존성 구성이란?

Gradle 프로젝트에 선언된 모든 의존성은 특정 범위에만 적용된다. 예를 들어, 일부 의존성은 소스 코드를 컴파일하는 데 사용해야 하는 반면 다른 의존성은 런타임에만 사용할 수 있어야 한다. Gradle은 구성을 통해 의존성의 범위를 명시한다. 모든 구성은 고유한 이름으로 식별할 수 있다.

많은 Gradle 플러그인은 프로젝트에 사전 정의된 구성을 추가한다. 예를 들어 java 플러그인은 소스 코드 컴파일, 테스트 실행 등에 필요한 다양한 클래스 경로를 나타내는 구성을 추가한다.

구성 상속 및 합성

구성은 다른 구성을 확장하여 상속 계층 구조를 형성할 수 있다. 하위 구성은 상위 구성에 대해 선언된 전체 의존성 집합을 상속한다.

구성 상속은 Java 플러그인과 같은 Gradle 핵심 플러그인에서 많이 사용된다. 예를 들어 testImplementationimplementation 구성을 확장한다. 여기에는 실용적인 목적이 있다. 테스트를 컴파일하려면 테스트 클래스를 작성하는 데 필요한 의존성 위에 테스트 대상 소스 코드의 의존성이 필요하다. 구성 상속은 Configuration.extendsFrom(org.gradle.api.artifacts.Configuration[]) 메소드를 호출하여 형성된다.

// build.gradle
configurations {
    smokeTest.extendsFrom testImplementation
}

dependencies {
    testImplementation 'junit:junit:4.13'
    smokeTest 'org.apache.httpcomponents:httpclient:4.5.5'
}

DependencyHandler

DependencyHandler는 의존성을 선언하는 데 사용된다. 의존성은 구성(configurations)으로 그룹화된다.

구성에 대한 특정 의존성을 선언하려면 다음 구문을 사용하면 된다.

dependencies {
    configurationName dependencyNotation
}

아래 예시는 의존성을 선언하는 기본적인 방법을 보여준다.

plugins {
    id 'java' // dependencies에 'implementation', 'testImplementation' 을 사용하기 위해
}

dependencies {
  //for dependencies found in artifact repositories you can use
  // 아티팩트 리포지토리에서 찾은 의존성의 경우 다음을 사용할 수 있다.
  //the group:name:version notation
  implementation 'commons-lang:commons-lang:2.6'
  testImplementation 'org.mockito:mockito:1.9.0-rc1'

  //map-style 표기법:
  implementation group: 'com.google.code.guice', name: 'guice', version: '1.0'

  //임의의 파일을 의존성으로 선언하기
  implementation files('hibernate.jar', 'libs/spring.jar')

  //'libs'의 모든 jars를 컴파일 클래스 경로에 넣기
  implementation fileTree('libs')
}

시리즈 내용 출처: gradle 공식 홈페이지

profile
@Ktown4u 개발자

0개의 댓글