일반적으로 maven
프로젝트에 의존성을 추가하려면 아래처럼 추가를 해야합니다.
<dependency>
<groupId>org.example.code</groupId>
<artifactId>example-depedency</artifactId>
<version>1.0.0</version>
</dependency>
프로젝트 도중 dependency
를 가져올때 무조건 latest
로 가져오다보니 다른 의존성 버전과 충돌이 됐습니다. 문제는 어떤 의존성과 왜 충돌되는지를 알 수가 없다는 것...
하나하나 테스트해가며 문제인 부분을 알아내야 하나..하던 차에 버전을 명시하지않아도 돌아가는 의존성들에 대한 궁금증이 생겨 아닌 밤중에 쫌쫌따리 구글링한걸 모아서 정리해보기로👏
핵심은 POM 파일들의 상속구조입니다.
parent 태그를 통한 상속 구조 :
pom.xml
->spring-boot-starter-parent
->spring-boot-dependencies
pom.xml 파일은 프로젝트 내 빌드 옵션, POM(Project Object Model)
을 설정하는 파일입니다.
pom.xml은 부모 pom.xml을 상속하여 미리 설정된 값이나 의존성들의 버전정보를 받아올수 있습니다.
<!-- pom.xml -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.4</version>
<relativePath/>
</parent>
<!-- spring-boot-starter-parent-2.5.4.pom -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.5.4</version>
</parent>
위처럼 pom.xml
은 spring-boot-starter-parent
을, spring-boot-starter-parent
은 spring-boot-dependencies
를 상속받은 것을 확인할 수 있습니다.
그리고 spring-boot-starter-parent
파일을 좀 더 살펴보면
<!-- spring-boot-starter-parent-2.5.4.pom -->
<properties>
<java.version>1.8</java.version>
<resource.delimiter>@</resource.delimiter>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
...
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/application*.yml</include>
<include>**/application*.yaml</include>
<include>**/application*.properties</include>
</includes>
</resource>
</resources>
기본적인 java
의 버전정보와 소스코드의 인코딩 타입과 같은 정보도 기록되어 있습니다.
또 스프링 부트의 환경설정 값을 적는 application.yml
이나 application.properties
리소스들도 추가해주는 정보가 적혀있습니다.
궁금했던 버전 자동 관리에 대한 부분은 spring-boot-dependencies
에서 찾을 수 있습니다.
<!-- spring-boot-dependencies-2.5.4.pom-->
<dependencyManagement>
<dependencies>
...
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>2.5.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<version>2.5.4</version>
</dependency>
...
...
</dependencies>
</dependencyManagement>
spring-boot-dependencies
를 열어보면 dependencyManagement
영역에 모든 버전정보들이 명시되어 있습니다. 위 영역에 존재하는 라이브러리를 사용하게 된다면 직접 버전을 명시하지 않아도 이곳에서 버전정보를 가져와 사용하게 됩니다.
<dependencyManagement>
를 통해 버전 선택에 대한 고민을 해결할 수 있습니다.또한 위와 같은 부모 pom 파일에 적힌 값들은 상속받은 자식 pom 오버라이드가 되기 때문에, 특별히 원하는 버전이 있는 경우에는 명시해도 됩니다.
그리고 pom에서 지원하지 않는 의존성 버전들은 버전을 명시해야합니다.
Parent pom
없이 dependencyManagement
사용하기spring-boot-starter-parent
를 사용하지 않고도 import scope dependency
를 이용하여 dependency management
기능을 사용 할 수 있습니다.
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.5.4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
만약 spring-boot-dependencies
중에서 특정 라이브러리만
다른 버전을 사용하기를 원한다면 spring-boot-dependencies
항목 전에 선언을 해야합니다.
그러나 parent
에서는 의존성만 가져오는 것이 아니라 java version
, encoding
, resource
, plugin
등 여러가지 다른 설정도 포함하기 때문에 바꿀 경우 많은 설정을 따로 진행해야 합니다.
https://stackoverflow.com/questions/29476472/maven-dependency-without-version
https://docs.spring.io/spring-boot/docs/2.4.2/maven-plugin/reference/htmlsingle/
https://velog.io/@hsw0194/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B6%80%ED%8A%B8%EC%9D%98-%EC%9D%98%EC%A1%B4%EC%84%B1-%EA%B4%80%EB%A6%AC
https://seongmun-hong.github.io/springboot/Spring-boot-dependency