build.gradle과 Dependencies

sameul__choi·2021년 11월 30일
2

Managing Dependencies of JVM Project

저번 포스팅에서 다루었던 Gradle에 이어서 우아한 테크코스 (pre) 과정 중 의문점이 들었던 부분에 대한 포스팅을 진행합니다. gradle에 있는 build.gradle 파일이 어떤 역할을 하는 지와, dependencies 프로퍼티에 대해서 알아보겠습니다.

build.gradle

Spring Boot Project를 위해서는 필연적으로 빌드 툴을 정하게 됩니다. 이 중 Gradle 빌드 툴을 선택하여 프로젝트를 실행시키면 자동으로 생기는 기본 파일 중 하나입니다. build.gradle 파일은 gradle에서 빌드 작업에 필요한 기본 설정, 동작 등을 정의한 파일이며 dependecy 또한 관리해주는 파일입니다.

plugins

프로젝트를 빌드하기 위해서는 여러 가지 작업을 처리해야 합니다. 대표적으로 컴파일 그리고 jar, war 등의 파일 생성 등이 있는데 이런 작업들을 해주는 plugins들이 필요합니다. plugins 블록 안에 필요한 플러그인을 지정해주면 plugins 들은 필요한 과정을 task로 포함하게 되고, 빌드할 때 모든 과정을 플러그인의 내부 task가 진행해줍니다.

id 'java'

사진을 보면 plugins 들 중에 id 'java'가 존재하는데 java는 Java 프로그램을 위한 기능을 제공하는 플러그인입니다. 대표적으로 compilJava라는 태스크가 있는데 이것은 java 플러그인이 제공해주는 기능 중 하나입니다.

repositories

repository는 저장소 정보를 관리하는 프로퍼티인데, 소프트웨어를 등록하고 관리하는 저장소를 가리키고 있습니다. 로컬이나 네트워크에 라이브러리를 공개하고 그 주소를 저장소로 등록하면 저장소에 있는 라이브러리를 Gradle이 취득하여 이용할 수 있습니다.

위의 사진에서는 mavenCentral()이라는 메서드를 통해 중앙 저장소를 사용하고 있습니다.

dependencies

dependencies는 의존성을 관리하고 설정하는 프로퍼티입니다. 여기에 필요한 라이브러리 등의 정보를 기술하면 그 라이브러리를 참조할 수 있게 됩니다.

dependencies를 사용할 때 Gradle 은 compile, implementation, testImplementation 등의 디 양한 옵션을 제공해줍니다.

compile

  • A 모듈을 수정하게 되면 이 모듈을 직 간접적으로 의존하는 모든 모듈이 recompile 된다.

implementation

  • A 모듈을 수정하게 되면 이 모듈을 직접 의존하는 모듈만 recompile 된다.

compileOnly

  • 컴파일 시에만 빌드하고 빌드 결과물에는 포함하지 않는다.
  • runtime 시 필요 없는 라이브러리인 경우를 말하는데 이 말은 즉 runtime 환경에 이미 라이브러리가 제공되고 있는 경우를 말한다.

runtimeOnly

  • runtime 시에만 필요한 라이브러리인 경우

annotationProcessor

  • Gradle 6.xx부터 "annotationProcessor"을 사용하면 별다른 설정을 하지 않아도 그레이들 자체에서 적절한 AnnotationProcessor를 선택하여 사용한다.

Dependencies의 Compile, implementation

관련 포스팅을 찾아 보던 중 어떤 포스팅에서는 implementation을 어떤 포스팅에서는 compile을 사용하는 경우가 있었습니다.

api(compile)

The dependencies required to compile the production source of the project which are part of the API exposed by the project. For example the project uses Guava and exposes public interfaces with Guava classes in their method signatures.

implementation

The dependencies required to compile the production source of the project which are not part of the API exposed by the project. For example the project uses Hibernate for its internal persistence layer implementation.

A를 의존하고 있는 모듈이 B, C라고 가정하자. 또한 모듈의 구조는 Example of modules와 같다고 가정하겠습니다.

Compile or api 사용 경우)
A라는 모듈을 수정하게 되면, 이 모듈을 직접 혹은 간접 의존하고 있는 B와 C는 모두 재빌드 되어야 합니다.

Implementation 사용 경우)
A라는 모듈을 수정하게 되면, 이 모듈을 직접 의존하고 있는 B만 재빌드합니다.

  • 맥락에서 재빌드(rebuild)라는 표현을 썼지만 recompile이랑 동일한 표현으로 사용되었습니다.

PS - Gradle 3.0부터는 Compile이 deprecated 되었습니다.

Implementation의 장점

- 빠른 속도

  • 구조만 보아도 dependency가 줄어든다는 점 변경사항이 발생하더라도 recompile을 적게 하기 때문에 소요되는 시간도 적습니다.

- API의 노출 방지

  • Design pattern에서 흔히 강조하는 내용 중에 하나로 Transparency가 있습니다. 안정성을 위해서 필요한 API만 노출하는 것이 중요하고 그것이 User 입장에서도 프로그램을 간편하게 사용할 수 있기 때문에 관리가 중요합니다. (Facade 패턴)

compile은 연결된 모든 모듈의 API가 노출되게 되므로 implementation을 사용했을 때의 장점이 될 수 있습니다.

✨참고한 블로그✨

0개의 댓글