일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 레벨2
- 의존성
- 서블릿
- mock
- JUnit5
- 우테코
- HTTP
- 우아한세미나
- 자바
- yml
- 코드리뷰
- Spring Batch
- AWS
- 프리코스
- AOP
- 우아한테크코스
- 스프링 부트
- 프로그래머스
- 세션
- 백준
- CircuitBreaker
- 스프링부트
- MSA
- Docker
- Level2
- 미션
- REDIS
- 트랜잭션
- Paging
- JPA
- Today
- Total
늘
[Gradle] runtimeOnly와 implementation와 testImplementation의 차이 본문
[Gradle] runtimeOnly와 implementation와 testImplementation의 차이
giron 2022. 3. 31. 01:02
평소에 runtimeOnly는 런타임 때 작동하겠지, implementation은 gradle이 돌아갈 때부터 작동하겠지라고 대충 생각하고 넘겨와서 그런지 막상 퀴즈를 받으니 대답을 못하겠다..
이번 기회에 공부하고 정리해보려고 한다.
일단 gradle에 의존성부터 확인해 보았다.
일단 눈에 띄었던 것은 빨간 박스로 표시한 것처럼 runtimeClasspath에 implementation으로 선언된 의존성 파일들이 들어있었다. 대충 implementation은 시작부터 runtime때까지 의존성이 살아있는구나(?)라고 생각했다.
CompileClasspath
- 에러 없이 컴파일을 하기 위해 필요한 클래스와 jar들의 위치를 나타낸다.
- compileClasspath만 잘 설정했다고 애플리케이션이 잘 작동하는 것은 아니다. 런타임에서 필요한 다른 클래스와 jar 가 필요할 수도 있기 때문이다.
RuntimeClasspath
- 애플리케이션이 정상적으로 실행하기 위해 필요한 클래스들과 jar들의 경로다.
예시
여러 글을 보았지만 가장 이해하기 쉬운 예시를 보아서 공유해보려고 한다.
class A{
public static void main(String[] args){
B b = new B();
}
}
class B {
public B() {
return new C().sum();
}
}
class C {
public int sum(){
return 5;
}
}
의존성의 방향은 A->B->C로 흐른다.
여기서 컴파일 시점에서는 A, B만 알면 된다. 런타임을 위해서는 C에 대한 정보도 가지고 있어야 한다.
A와 B에 대한 컴파일 타임 의존성을 가지고 있는 것이며, A, B, C에 대해 런타임 의존성을 가지고 있는 것이다.
이렇게 보면 맨 처음 스샷이 이해가 간다.
만약 B에 대한 dependency를 implementation으로 설정하게 되면 B의 모듈만 가져오게 되고, compile path에는 B만 들어가게 된다.
즉, 컴파일 타임에서 사용자(A를 정의한 이용자)는 C를 알 수가 없다.(또는 알 필요가 없다.) 그리고 C가 수정되었다고 하더라도 A를 다시 컴파일할 필요가 없다. 오직 B만 컴파일을 하면 된다.
반면에 api로 설정하면 C의 모듈까지 알게 되고 컴파일 시에 C까지 재빌드하므로 불필요하다면 사용하지 않는 게 좋다.
testImplementation은 테스트 코드를 수행할 때만 적용된다고 한다.
compileOnly
- compileClassPath에만 추가하겠다는 뜻이다.
- 빌드 결과물의 사이즈가 줄어드는 장점이 있다.
- ex) lombok -> gradle5 부터 compileOnly 대신 annotationprocessor를 사용해야 한다.
컴파일 시에 getter, setter 등 필요한 것을 생성시키고, 런타임 때에는 사용하지 않기 때문이다.
runtimeOnly
- runtimeClassPath에만 추가하겠다
- 해당 클래스에서 코드 변경이 발생해도 컴파일을 다시 할 필요가 없다는 장점이 있다.
- ex) DB나 로그 관련 dependency
Reference
'백앤드 개발일지 > 스프링부트' 카테고리의 다른 글
@RestController와 @ResponseBody없이 json으로 통신하는 방법 (2) | 2022.04.30 |
---|---|
@RequestBody와 @ModelAttribute 차이 (0) | 2022.04.27 |
[아키텍처] 계층형 아키텍처와 MSA (2) | 2022.02.11 |
[스프링 싱글톤] Bean과 Component 차이 (0) | 2022.01.14 |
[webflux] webclient 이슈 정리 (2) | 2022.01.04 |