Maven真——聚合和继承(于)
依赖管理
我们谈论继承一个dependencies因素,我们非常easy这个特性被认为是适用于accout-parent于。
子模块account-email和account-persist同一时候依赖了org.springframework:spring-core:2.5.6,spring-beans:2.5.6,spring-context:2.5.6,junit:junit:4.7。以此能够将这些公共依赖放到父模块account-parent中,两个子模块就能移除这些依赖,简化配置。
上述方法时可行的,可是有问题。
由于我们无法确定将来加入子模块就一定须要这四个模块依赖。
Maven提供dependencyManagement元素既能让子模块继承到父模块的依赖配置。又能保证子模块依赖使用的灵活性。在dependencyManagement元素下依赖声明不会引入实际的依赖。只是他能够约束dependencies下依赖的使用。
比如。能够在account-parent下加入这样的dependencyManagement配置,代码例如以下:
<modelVersion>4.0.0</modelVersion>
<groupId>com.juvenxu.mvnbook.account</groupId>
<artifactId>account-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Account Parent</name>
<properties>
<springframework.version>2.5.6</springframework.version>
<junit.version>4.7</junit.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
如今改动account-email配置例如以下
<properties>
<javax.mail.version>1.4.1</javax.mail.version>
<greenmail.version>1.3.1b</greenmail>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${springframework.version}</version>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>${junit.mail.version}</version>
</dependency>
<dependency>
<groupId>com.icegreen</groupId>
<artifactId>greenmail</artifactId>
<version>${greenmail.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
使用这样的依赖管理机制似乎不能降低太多了POM配置,可是我还是强烈推荐採用这样的方法。
原因是在于父pom中使用dependencyManagement声明依赖能够统一项目范围中依赖的版本号,降低依赖的冲突。
假设子模块中不声明依赖的使用,即使该依赖已经在父pom的dependencyManagement中声明了也不会产生不论什么实际的效果,假设account-persist:
<properties>
<dom4j.version>1.6.1</dom4j.version>
</properties>
<dependencies>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>${dom4j.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
</dependencies>
这里没有声明spring-context-support。那么该依赖就不会被引入。
这里顺便提一下import的依赖范围,这个依赖范围仅仅在dependencyManagement元素下才有效果。使用该范围的依赖通常指向一个POM,作用是将目标POM中的dependencyManagement配置导入并合并到当前pom的dependencyManagement元素中。比如:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.juvenxu.mvnbook.account</groupId>
<artifactId>account-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
插件管理
Maven提供了dependencyManagement元素帮助管理依赖,相似的Maven也提供了pluginManagement元素帮助管理插件。在该元素中配置的依赖不会造成实际的插件调用行为,当POM中配置了真正了plugin元素,而且其groupId和artifactId与pluginManagement中配置的插件匹配时。pluginManagement的配置才会影响到实际的插件行为
比如:
<bulid>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.1</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>verify</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
<execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</bulid>
将其jar-no-fork目标绑定到了verity生命周期阶段,以生成项目源代码包,当子模块须要生成源代码包的时候,仅仅须要例如以下简单的配置。代码例如以下:
<bulid>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<plugin>
</plugins>
</build>
假设子模块须要不同于父模块的插件配置,能够自行配置以覆盖父模块的pluginManagement配置。有了pluginManagement元素,account-email和account-persist的pom也得以简化。
他们都配置了maven-compiler-plugin和maven-resoureces-plugin。能够将这两个插件配置移到account-parent的pluginManagement元素中。
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugins>
</pluginManagement>
</build>
account-email和accoun-persist能够全然移除关于maven-compiler-plugin和maven-resources-plugin的配置,但他们仍能享受这两个插件服务。
当项目的多个模块有相同的插件配置时,应当将配置移到父pom的pluginManagement的元素中。
即使各个模块对同一个插件的详细配置不尽相同,也应当使用父pom的pluginManagement元素统一声明插件的版本号。甚至能够要求将全部用到的插件的版本号在父pom的pluginManagement元素中声明,子模块使用插件时不配置版本号信息。这么做能够统一项目的插件版本号,避免潜在的插件不一致或者不稳定问题。也更易于维护。