pom.xml 메이븐 - 종속성 관리와 Maven의 종속성 간의 차이점




종류 레파지토리 (9)

당신이 말한 것과 같습니다. dependencyManagement 는 모든 종속성 정보를 공통 POM 파일로 가져와 하위 POM 파일의 참조를 단순화하는 데 사용됩니다.

여러 하위 프로젝트에서 다시 입력하지 않으려는 여러 속성이있는 경우 유용합니다.

마지막으로 dependencyManagement 를 사용하여 여러 프로젝트에서 사용할 표준 버전의 이슈를 정의 할 수 있습니다.

dependencyManagementdependencies 의 차이점은 무엇입니까? Apache Maven 웹 사이트에서 문서를 보았습니다. dependencyManagement에 정의 된 dependencyManagement 은 버전을 지정하지 않고 자식 모듈에서 사용할 수 있습니다.

예 :

상위 프로젝트 (Pro-par)는 종속성 관리 아래 종속성을 정의합니다.

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8</version>
    </dependency>
 </dependencies>
</dependencyManagement>

그렇다면 프로 파 (Pro-par)의 자녀는 junit을 사용할 수 있습니다.

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
    </dependency>
 </dependencies>

그러나 부모 pom에 junit을 정의해야하는지 궁금합니다. 왜 그것을 필요한 모듈에서 직접 정의하지 않습니까?


종속성이 최상위 레벨의 dependencyManagement 요소에 정의 된 경우, 하위 프로젝트는 종속성의 버전을 명시 적으로 나열 할 필요가 없습니다. 하위 프로젝트가 버전을 정의한 경우 최상위 POM의 dependencyManagement 섹션에 나열된 버전보다 우선합니다. 즉, dependencyManagement 버전은 자식이 버전을 직접 선언하지 않을 때만 사용됩니다.


메이븐 사이트의 문서 는 끔찍합니다. dependencyManagement가하는 일은 단순히 의존성 정의 (버전, 제외 등)를 상위 pom으로 이동 한 다음 하위 폼에서 groupId 및 artifactId를 넣기 만하면됩니다. 부모 덤프 체킹 (parent pom chaining) 등을 제외하고는 그렇지만, 그게 사실 복잡하지는 않습니다 .- 의존성 관리가 부모 레벨의 의존성을이기는 것입니다.하지만, 그 또는 수입에 관한 질문이 있다면, Maven 문서가 조금 낫습니다.)

Maven 사이트에서 'a', 'b', 'c'가비지를 모두 읽고 혼란 스러울 때, 나는 그들의 예를 다시 썼다. 따라서 공통 종속성 (betaShared)을 공유하는 2 개의 프로젝트 (proj1과 proj2)가 있다면 그 종속성을 상위 pom으로 이동할 수 있습니다. 그 동안 프로젝트에 의미가있는 경우에만 다른 의존성 (알파 및 찰리)을 이동할 수도 있습니다. 따라서 앞 문장에 설명 된 상황에서 부모 POM에 dependencyManagement가있는 해결책이 있습니다.

<!-- ParentProj pom -->
<project>
  <dependencyManagement>
    <dependencies>
      <dependency> <!-- not much benefit defining alpha here, as we only use in 1 child, so optional -->
        <groupId>alpha</groupId>
        <artifactId>alpha</artifactId>
        <version>1.0</version>
        <exclusions>
          <exclusion>
            <groupId>zebra</groupId>
            <artifactId>zebra</artifactId>
          </exclusion>
        </exclusions>
      </dependency>
      <dependency>
        <groupId>charlie</groupId> <!-- not much benefit defining charlie here, so optional -->
        <artifactId>charlie</artifactId>
        <version>1.0</version>
        <type>war</type>
        <scope>runtime</scope>
      </dependency>
      <dependency> <!-- defining betaShared here makes a lot of sense -->
        <groupId>betaShared</groupId>
        <artifactId>betaShared</artifactId>
        <version>1.0</version>
        <type>bar</type>
        <scope>runtime</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>

<!-- Child Proj1 pom -->
<project>
  <dependencies>
    <dependency>
      <groupId>alpha</groupId>
      <artifactId>alpha</artifactId>  <!-- jar type IS DEFAULT, so no need to specify in child projects -->
    </dependency>
    <dependency>
      <groupId>betaShared</groupId>
      <artifactId>betaShared</artifactId>
      <type>bar</type> <!-- This is not a jar dependency, so we must specify type. -->
    </dependency>
  </dependencies>
</project>

<!-- Child Proj2 -->
<project>
  <dependencies>
    <dependency>
      <groupId>charlie</groupId>
      <artifactId>charlie</artifactId>
      <type>war</type> <!-- This is not a jar dependency, so we must specify type. -->
    </dependency>
    <dependency>
      <groupId>betaShared</groupId> 
      <artifactId>betaShared</artifactId> 
      <type>bar</type> <!-- This is not a jar dependency, so we must specify type. -->
    </dependency>
  </dependencies>
</project>

부모 POM에서 <dependencies><dependencyManagement> 의 주요 차이점은 다음과 같습니다.

<dependencies> 섹션에 명시된 아티팩트는 항상 하위 모듈의 종속성으로 포함됩니다.

섹션에 지정된 아티팩트는 하위 모듈 자체의 섹션에도 지정되어있는 경우에만 하위 모듈에 포함됩니다. 왜 당신이 물어 보는 것이 좋은가요? 부모에서 버전 및 / 또는 범위를 지정하고 하위 POM에서 종속성을 지정할 때이 버전 및 / 또는 범위를 생략 할 수 있기 때문입니다. 이렇게하면 각 하위 모듈에 버전을 지정하지 않고 하위 모듈에 대한 종속성에 통합 된 버전을 사용할 수 있습니다.


충분히 강조 표시되지 않은 한 가지가 있습니다. 제 생각에는 원치 않는 상속 입니다.

다음은 점증적인 예입니다.

나는 parent pom에서 선언합니다.

<dependencies>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>19.0</version>
        </dependency>
</dependencies>

팔! 나는 그것을 Child A , Child BChild C 모듈에 가지고 있습니다.

  • 아동복에 의해 상속 된 상식
  • 관리 할 단일 장소
  • 아이 수확기에서 무엇이든 다시 생각할 필요가 없다.
  • 원하는 경우 Child B 를 다시 돌보고 version 18.0 대체 할 수 있습니다.

그러나 내가 Child C 에서 구아바를 필요로하지 않게되고, 미래의 Child DChild E 모듈에서 구아나를 필요로하지 않으면 어떻게 될까요?

그들은 여전히 ​​그것을 상속받을 것이며 이것은 바람직하지 않습니다! 이것은 Java God Object Code 냄새와 같으며, 클래스에서 유용한 비트를 상속받으며 불필요한 항목도 많이 상속받습니다.

이것이 <dependencyManagement> 가 시작되는 곳입니다. 이것을 부모 pom에 추가하면 모든 하위 모듈이 멈 춥니 . 따라서 여러분은 그것을 필요로하는 각 개별 모듈에 들어가서 다시 선언해야합니다 (버전이 없어도 Child AChild B ).

그리고, 분명히, 당신은 Child C 위해서 그렇게하지 않으므로, 당신의 모듈은 마른 체형을 유지합니다.


종속성 관리를 사용하면 모든 자식이 상속하는 종속성을 추가하지 않고도 종속성 버전 관리를 통합하고 중앙 집중화 할 수 있습니다. 이는 공통 상위를 상속하는 일련의 프로젝트 (예 : 두 개 이상의 프로젝트)있는 경우 특히 유용합니다.

dependencyManagement 또 다른 매우 중요한 사용 사례는 전이 종속성에 사용되는 아티팩트 버전 제어입니다. 예제가 없으면 설명하기가 어렵습니다. 다행히도, 이것은 문서에 설명되어 있습니다.


Eclipse에는 dependencyManagement 에 하나 더 많은 기능이 있습니다. dependencies 을 사용하지 않으면 pom 파일에서 근본적인 의존성을 발견하게됩니다. dependencyManagement 가 사용되는 경우, pom 파일에 미해결 종속성이 남아 있고 java 파일에만 오류가 나타납니다. (수입품 등 ...)


나는이 질문에 유행에 뒤늦지 만 받아 들인 답보다 명확한 답변을 할 가치가 있다고 생각한다. (맞지만 실제 중요한 부분을 강조하지는 않는다.

부모 POM에서 <dependencies><dependencyManagement> 의 주요 차이점은 다음과 같습니다.

<dependencies> 섹션에 명시된 아티팩트는 항상 하위 모듈의 종속성으로 포함됩니다.

<dependencyManagement> 섹션에 지정된 아티팩트는 하위 모듈 자체의 <dependencies> 섹션에도 지정되어있는 경우에만 하위 모듈에 포함됩니다. 왜 당신이 물어 보는 것이 좋은가요? 부모에서 버전 및 / 또는 범위를 지정하고 하위 POM에서 종속성을 지정할 때이 버전 및 / 또는 범위를 생략 할 수 있기 때문입니다. 이렇게하면 각 하위 모듈에 버전을 지정하지 않고 하위 모듈에 대한 종속성에 통합 된 버전을 사용할 수 있습니다.


간단한 일이 있습니다. dependencyManagement실제로 사용되는 종속성을 선언하지 않으며 사용할 있는 버전 만 정의합니다.

이와 같이 정의하면 변경되지 않습니다.

<properties>
    <guava.version>18.0</guava.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>${guava.version}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

트리에서 사용되는 버전을 정말로 덮어 쓰고 싶다면 실제 의존성을 정의 할 필요가 있습니다. 위의 정의에 따라 다음을 추가해야합니다 :

<dependencies>
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
    </dependency>
</dependencies>

추가 한 경우 mvn dependency:tree 를 통해 나중에 확인하십시오.





maven pom.xml dependency-management