zoukankan      html  css  js  c++  java
  • (转)Maven中的DependencyManagement和pluginmanagement

    背景:最近在学习maven的多模块构建过程中看到DependencyManagement选项,对这个选项的使用做个记录!

     区别与联系

    这里介绍一个在父项目中的根结点中声明dependencyManagement和dependencies的区别

    dependencyManagement使用

    dependencyManagement只会影响现有依赖的配置,但不会引入依赖。

    例如我们可以在父模块中配置如下:

    <dependencyManagement>
      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactid>junit</artifactId>
          <version>4.8.2</version>
          <scope>test</scope>
        </dependency>
        <dependency>
          <groupId>log4j</groupId>
          <artifactid>log4j</artifactId>
          <version>1.2.16</version>
        </dependency>
      </dependencies>
    </dependencyManagement>

    这段配置不会给任何子模块引入依赖,但如果某个子模块需要使用JUnit和Log4j的时候,我们就可以简化依赖配置成这样:

     <dependency>
        <groupId>junit</groupId>
        <artifactid>junit</artifactId>
      </dependency>
      <dependency>
        <groupId>log4j</groupId>
        <artifactid>log4j</artifactId>
      </dependency>

    现在只需要groupId和artifactId,其它元素如version和scope都能通过继承父POM的dependencyManagement得到,如果有依赖配置了exclusions,那节省的代码就更加可观。但重点不在这,重点在于现在能够保证所有模块使用的JUnit和Log4j依赖配置是一致的。而且子模块仍然可以按需引入依赖,如果我不配置dependency,父模块中dependencyManagement下的spring-aop依赖不会对我产生任何影响。

    也许你已经意识到了,在多模块Maven项目中,dependencyManagement几乎是必不可少的,因为只有它是才能够有效地帮我们维护依赖一致性。

    dependencies

    相对于dependencyManagement,所有声明在dependencies里的依赖都会自动引入,并默认被所有的子项目继承。

    classifier

    如果你要发布同样的代码,但是由于技术原因需要生成两个单独的构件,你就要使用一个分类器(classifier)。例如,如果你想要构建两个单独的构件成JAR,一个使用Java 1.4 编译器,另一个使用Java 6 编译器,你就可以使用分类器
    来生成两个单独的JAR构件,它们有同样的groupId:artifactId:version组合。如果你的项目使用本地扩展类库,你可以使用分类器为每一个目标平台生成一个构件。分类器常用于打包构件的源码,JavaDoc 或者二进制集合。

    dependencyManagement精进

    我们知道Maven的继承和Java的继承一样,是无法实现多重继承的,如果10个、20个甚至更多模块继承自同一个模块,那么按照我们之前的做法,这个父模块的dependencyManagement会包含大量的依赖。

    如果你想把这些依赖分类以更清晰的管理,那就不可能了,import scope依赖能解决这个问题。你可以把dependencyManagement放到单独的专门用来管理依赖的POM中,然后在需要使用依赖的模块中通过import scope依赖,就可以引入dependencyManagement。

    例如可以写这样一个用于依赖管理的POM

    <project>
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.juvenxu.sample</groupId>
      <artifactId>sample-dependency-infrastructure</artifactId>
      <packaging>pom</packaging>
      <version>1.0-SNAPSHOT</version>
      <dependencyManagement>
        <dependencies>
            <dependency>
              <groupId>junit</groupId>
              <artifactid>junit</artifactId>
              <version>4.8.2</version>
              <scope>test</scope>
            </dependency>
            <dependency>
              <groupId>log4j</groupId>
              <artifactid>log4j</artifactId>
              <version>1.2.16</version>
            </dependency>
        </dependencies>
      </dependencyManagement>
    </project>

    然后我就可以通过非继承的方式来引入这段依赖管理配置:

    <dependencyManagement>
        <dependencies>
            <dependency>
              <groupId>com.juvenxu.sample</groupId>
              <artifactid>sample-dependency-infrastructure</artifactId>
              <version>1.0-SNAPSHOT</version>
              <type>pom</type>
              <scope>import</scope>
            </dependency>
        </dependencies>
      </dependencyManagement>
    
      <dependency>
        <groupId>junit</groupId>
        <artifactid>junit</artifactId>
      </dependency>
      <dependency>
        <groupId>log4j</groupId>
        <artifactid>log4j</artifactId>
      </dependency>

    这样,父模块的POM就会非常干净,由专门的packaging为pom的POM来管理依赖,也契合的面向对象设计中的单一职责原则。此外,我们还能够创建多个这样的依赖管理POM,以更细化的方式管理依赖。

    这种做法与面向对象设计中使用组合而非继承也有点相似的味道。

    plugins和pluginmanagement的区别

    pluginmanagement标签一般用在父pom中,子元素可以包含plugins插件,比如

    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <version>2.1</version>
                <configuration>
                    <attach>true</attach>
                </configuration>
                <executions>
                    <execution>
                        <phase>compile</phase>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </pluginManagement>

    然后,在子pom文件中就可以这样使用:

    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
        </plugin>
    </plugins>

    省去了版本、配置等信息,只需指定groupId和artifactId即可。

    但是在父pom中,如果使用这个标签来包裹plugins插件,当在此项目根目录运行对应的mvn命令时,如果在子pom中没有直接像上面再次引用这个plugin,那么不会触发这个plugin插件,只有在子pom中再次引用了之后,才会在对应的子项目路径下触发这个plugin.

    plugins和pluginManagement标签都需要在build标签中。

    关于插件pluginManagement,Maven并没有提供与import scope依赖类似的方式管理,那我们只能借助继承关系,不过好在一般来说插件配置的数量远没有依赖配置那么多,因此这也不是一个问题。

  • 相关阅读:
    [No00004E]千万不要“拼命”工作——写在滴滴总裁柳青患癌症之后
    [No00004D]深度思考好文:软件工程师的困境
    [No00004C]软件工程师的创业陷阱:接私活
    [No00004B]Windows 下面为Python3.5安装NoteBook
    [No00004A]为什么你看了很多书,却依然没有洞见
    [No000049]狗日的中年——姜文
    [No000048]程序员的成长过程中,有哪些阶段?
    [No000047]好的架构源于不停地衍变,而非设计
    [No000046]为什么跳槽加薪会比内部调薪要高?
    [No000045]最好的休息,不是睡觉!
  • 原文地址:https://www.cnblogs.com/lixuwu/p/8058365.html
Copyright © 2011-2022 走看看