[maven] Maven의 종속성 관리와 종속성의 차이점

차이점은 무엇이며 dependencyManagement그리고 dependencies? Apache Maven 웹 사이트에서 문서를 보았습니다. dependencyManagement하위 버전에서 버전을 지정하지 않고 하위 모듈에서 정의 된 종속성을 사용할 수있는 것 같습니다 .

예를 들면 다음과 같습니다.

상위 프로젝트 (Pro-par)는 다음에 따라 종속성을 정의합니다 dependencyManagement.

<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에서와의 주요 차이점은 다음 <dependencies><dependencyManagement>같습니다.

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

<dependencyManagement>섹션에 지정된 아티팩트 <dependencies>는 하위 모듈 자체 의 섹션 에도 지정된 경우에만 하위 모듈에 포함됩니다. 물어 보는 것이 왜 좋은가요? 상위에서 버전 및 / 또는 범위를 지정하고 하위 POM에서 종속성을 지정할 때이를 제외 할 수 있습니다. 이를 통해 각 하위 모듈에 버전을 지정하지 않고도 하위 모듈의 종속성에 통합 버전을 사용할 수 있습니다.


답변

Maven 사이트 의 문서 는 끔찍합니다. dependencyManagement가하는 일은 단순히 의존성 정의 (버전, 제외 등)를 상위 pom으로 이동 한 다음 자식 폼에서 groupId 및 artifactId를 넣어야합니다. 그게 다입니다 (부모 퐁 체인 등은 제외하지만 실제로는 복잡하지 않습니다)

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>


답변

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

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

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


답변

내 의견으로는 여전히 강조되지 않은 것은 원치 않는 상속 입니다.

다음은 증분 예입니다.

나는 내 parent퐁으로 선언합니다 .

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

팔! 나는 그것을 가지고 Child A, Child BChild C모듈 :

  • 아동 치어에 의해 상속 된 허점
  • 관리 할 단일 장소
  • 아동 치어에서 아무것도 다시 선언 할 필요가 없습니다.
  • 나는 아직도 redelcare 및 재정의 할 수 있습니다 version 18.0A의 Child B내가 원하는 경우.

그러나에 구아바가 필요 Child C하지 않고 미래 Child DChild E모듈 모두에서 결과를 얻지 못하면 어떻게 될까요?

그들은 여전히 ​​그것을 상속받을 것이며 이것은 바람직하지 않습니다!
이것은 Java God Object 코드 냄새와 유사합니다. 여기서 클래스에서 유용한 비트와 원치 않는 많은 것들을 상속합니다.

여기가 시작 <dependencyManagement>됩니다. 이것을 부모 pom에 추가하면 모든 자식 모듈이 멈 춥니 . 따라서 당신이하는 강제 (않는이 필요로하는 각 개별 모듈로 이동하고 다시 선언 Child A하고 Child B버전 생각하지 않고).

그리고 분명히, 당신은 그것을하지 않기 Child C때문에 모듈은 마른 상태로 유지됩니다.


답변

차이 요약 몇 가지 답변이 있습니다 <depedencies><dependencyManagement>받는다는와 태그.

그러나 간결한 방법으로 아래에 자세히 설명 된 몇 가지 사항이 있습니다.

  1. <dependencyManagement>다양한 모듈에서 사용되는 모든 종속성 (자식 퐁 수준에서 사용)을 통합 할 수 있습니다. 명확성 , 중앙 종속성 버전 관리
  2. <dependencyManagement>필요에 따라 종속성을 쉽게 업그레이드 / 다운 그레이드 할 수 있습니다. 다른 시나리오에서는 모든 하위 폼 레벨에서 일관성을 유지해야합니다.
  3. <dependencies>태그에 제공된 종속성 은 항상 가져 오는 반면, <dependencyManagement>상위 pom에 제공된 종속성은 하위 pom에 <dependencies>태그에 해당 항목이있는 경우에만 가져옵니다 .

답변

파티에 늦어서 미안해

mvn dependency:tree명령을 사용하여 차이점을 설명하려고합니다.

아래 예를 고려하십시오

부모 POM-내 프로젝트

<modules>
    <module>app</module>
    <module>data</module>
</modules>

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

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.9</version>
        </dependency>
    </dependencies>
</dependencyManagement>

자식 POM-데이터 모듈

<dependencies>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
    </dependency>
</dependencies>

하위 POM-앱 모듈 (추가 종속성이 없으므로 종속성을 비워 둡니다)

 <dependencies>
</dependencies>

mvn dependency:tree명령을 실행 하면 다음과 같은 결과가 나타납니다.

Scanning for projects...
------------------------------------------------------------------------
Reactor Build Order:

MyProject
app
data

------------------------------------------------------------------------
Building MyProject 1.0-SNAPSHOT
------------------------------------------------------------------------

--- maven-dependency-plugin:2.8:tree (default-cli) @ MyProject ---
com.iamvickyav:MyProject:pom:1.0-SNAPSHOT
\- com.google.guava:guava:jar:19.0:compile

------------------------------------------------------------------------
Building app 1.0-SNAPSHOT
------------------------------------------------------------------------

--- maven-dependency-plugin:2.8:tree (default-cli) @ app ---
com.iamvickyav:app:jar:1.0-SNAPSHOT
\- com.google.guava:guava:jar:19.0:compile

------------------------------------------------------------------------
Building data 1.0-SNAPSHOT
------------------------------------------------------------------------

--- maven-dependency-plugin:2.8:tree (default-cli) @ data ---
com.iamvickyav:data:jar:1.0-SNAPSHOT
+- org.apache.commons:commons-lang3:jar:3.9:compile
\- com.google.guava:guava:jar:19.0:compile

Google 구아바 는 모든 모듈 (부모 포함)에서 종속성으로 표시되는 반면 아파치 커먼 은 데이터 모듈에서만 (부모 모듈이 아닌) 종속성으로 표시됩니다.