Maven中的继承实例(下)
2015-07-21 19:39
375 查看
可继承的元素
在maven的POM中,groupId和version是可以被继承的,那么还有哪些POM元素是可以被继承的呢?以下是一个完整的列表:
groupId:项目组ID,项目坐标的核心元素
version:项目版本,项目坐标的核心元素
description:项目的描述信息
organization:项目的组织信息
inceptionYear:项目的创始年份
url:项目的URL地址
developers:项目的开发者信息
contributors:项目的贡献者信息
distributionManagement:项目的部署信息
issueManagement:项目的缺陷跟踪系统信息
ciManagement:项目的持续集成系统信息
scm:项目的版本控制系统信息
mailingLists:项目的邮件列表信息
properties:项目的依赖配置
dependencies:项目的依赖配置
dependencyManagement:项目的依赖管理配置
repositories:项目的仓库配置
build:包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等
reporting:包括项目的报告输出目录配置、报告插件配置等
依赖管理
可继承元素从上面可以看到包含dependencies元素,说明依赖是会被继承的,这时我们就可以考虑把这一特性应用到account-parent中。子模块account-email和account-persist同时依赖了spring-core等,可以将这些依赖配置放到父模块account-parent中,两个子模块就可以移除这些依赖,简化配置。
上述做法是可行的,但却存在问题。到目前为止,我们能够确定这两个子模块都包含这四个依赖,不过我们无法确定将来添加的子模块就一定需要这四个依赖。假设添加一个不需要spring依赖的子模块,那又该怎么处理呢?
Maven提供了一个dependencyManagement元素,它既能让子模块继承到父模块的以来配置,又能保证子模块以来使用的灵活性。在dependencyManagement元素下的依赖声明不会引入实际的依赖,不过它能够约束dependecies下的依赖使用。例如,可以在account-parent中加入dependencyManagement配置,如下:
//account-parent的pom.xml
首先该父POM使用归类依赖的方法,将springframework和junit依赖的版本以Maven变量的形式提取了出来,不仅消除了重复,还使各依赖的版本处于更明显的位置。
这里使用dependencyManagement声明的依赖既不会给account-parent引入依赖,也不会给它的子模块引入依赖,不过这段配置会被继承。现在修改account-email的POM,如下
//account-email的pom.xml
使用这种依赖管理机制貌似不能减少太多POM配置,但使用dependencyManagement声明能够统一项目规范中依赖的版本,当依赖版本在父PM中声明之后,子模块在使用依赖的时候就无须声明版本,也就不会发生多个子模块使用依赖版本不一致的情况。这可以帮助降低依赖冲突的几率。
如果子模块不声明依赖的使用,即使该依赖已经在父POM的dependencyManagement中声明了,也不会产生任何实际的效果,如account-persist的POM
//account-persist的pom.xml
另外除了复制配置或者继承方式,还可以使用import范围依赖将配置导入,示例如下:
插件管理
Mavan提供了dependencyManag元素帮助管理依赖,类似地,Maven也提供了pluginManag元素帮助管理插件。在该元素中的配置并不会造成实际的插件调用行为,当POM中配置了真正的plugin元素,并且其groupId和artifactId与pluginManagement中配置的插件匹配时,pluginManagement的配置才会影响实际的插件行为。
//account-parent配置pluginManagement后的pom.xml
当项目中的多个模块有同样的插件配置时,应当将配置移到父POM的pluginManagement元素中。即使各个模块对于同一插件的具体配置不尽相同,也应当使用父POM的pluginManagement元素统一生命擦肩的版本。甚至可以要求将所有用到的插件的版本在父POM的pluginManagement元素中声明,子模块使用插件时不配置版本信息,这么做可以同一项目的插件版本,避免潜在的插件不一致或者不稳定问题,也更易于维护。
参考:《Maven实战》第8章——徐晓斌著
在maven的POM中,groupId和version是可以被继承的,那么还有哪些POM元素是可以被继承的呢?以下是一个完整的列表:
groupId:项目组ID,项目坐标的核心元素
version:项目版本,项目坐标的核心元素
description:项目的描述信息
organization:项目的组织信息
inceptionYear:项目的创始年份
url:项目的URL地址
developers:项目的开发者信息
contributors:项目的贡献者信息
distributionManagement:项目的部署信息
issueManagement:项目的缺陷跟踪系统信息
ciManagement:项目的持续集成系统信息
scm:项目的版本控制系统信息
mailingLists:项目的邮件列表信息
properties:项目的依赖配置
dependencies:项目的依赖配置
dependencyManagement:项目的依赖管理配置
repositories:项目的仓库配置
build:包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等
reporting:包括项目的报告输出目录配置、报告插件配置等
依赖管理
可继承元素从上面可以看到包含dependencies元素,说明依赖是会被继承的,这时我们就可以考虑把这一特性应用到account-parent中。子模块account-email和account-persist同时依赖了spring-core等,可以将这些依赖配置放到父模块account-parent中,两个子模块就可以移除这些依赖,简化配置。
上述做法是可行的,但却存在问题。到目前为止,我们能够确定这两个子模块都包含这四个依赖,不过我们无法确定将来添加的子模块就一定需要这四个依赖。假设添加一个不需要spring依赖的子模块,那又该怎么处理呢?
Maven提供了一个dependencyManagement元素,它既能让子模块继承到父模块的以来配置,又能保证子模块以来使用的灵活性。在dependencyManagement元素下的依赖声明不会引入实际的依赖,不过它能够约束dependecies下的依赖使用。例如,可以在account-parent中加入dependencyManagement配置,如下:
//account-parent的pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <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>4.1.7.RELEASE</springframework.version> <junit.version>4.12</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> </project>
首先该父POM使用归类依赖的方法,将springframework和junit依赖的版本以Maven变量的形式提取了出来,不仅消除了重复,还使各依赖的版本处于更明显的位置。
这里使用dependencyManagement声明的依赖既不会给account-parent引入依赖,也不会给它的子模块引入依赖,不过这段配置会被继承。现在修改account-email的POM,如下
//account-email的pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <artifactId>account-email</artifactId> <name>Account Email</name> <parent> <groupId>com.juvenxu.mvnbook.account</groupId> <artifactId>account-parent</artifactId> <version>1.0.0-SNAPSHOT</version> <relativePath>../account-parent/pom.xml</relativePath> </parent> <properties> <javax.mail.version>1.4</javax.mail.version> <greenmail.version>1.4.1</greenmail.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>${javax.mail.version}</version> </dependency> <dependency> <groupId>com.icegreen</groupId> <artifactId>greenmail</artifactId> <version>${greenmail.version}</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.7</source> <target>1.7</target> </configuration> <version>2.3.2</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <configuration> <encoding>UTF-8</encoding> </configuration> <version>2.5</version> </plugin> </plugins> </build> </project>上述POM中的依赖配置较原来简单了一些,所有的springframework依赖只配置了groupId和artifactId,省去了version,而junit依赖不仅省去了version,还省去了依赖范围scope。这些信息可以省略是因为account-email继承了account-parent中的dependencyManagement配置,完整的依赖声明已经包含在父POM中,子模块只需要配置简单的groupId和artifactId就能获得对应的依赖信息,从而引入正确的依赖。
使用这种依赖管理机制貌似不能减少太多POM配置,但使用dependencyManagement声明能够统一项目规范中依赖的版本,当依赖版本在父PM中声明之后,子模块在使用依赖的时候就无须声明版本,也就不会发生多个子模块使用依赖版本不一致的情况。这可以帮助降低依赖冲突的几率。
如果子模块不声明依赖的使用,即使该依赖已经在父POM的dependencyManagement中声明了,也不会产生任何实际的效果,如account-persist的POM
//account-persist的pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <artifactId>account-persist</artifactId> <name>Account Persist</name> <parent> <groupId>com.juvenxu.mvnbook.account</groupId> <artifactId>account-parent</artifactId> <version>1.0.0-SNAPSHOT</version> <relativePath>../account-parent/pom.xml</relativePath> </parent> <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> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> </dependency> </dependencies> <build> <testResources> <testResource> <directory>src/test/resources</directory> <filtering>true</filtering> </testResource> </testResources> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.7</source> <target>1.7</target> </configuration> <version>2.3.2</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <configuration> <encoding>UTF-8</encoding> </configuration> <version>2.5</version> </plugin> </plugins> </build> </project>这里没有声明spring-context-support,那么该依赖就不会被引入,这真是dependencyManagement的灵活性所在。
另外除了复制配置或者继承方式,还可以使用import范围依赖将配置导入,示例如下:
<dependencyManagement> <dependencies> <dependency> <groupId>com.juvenxu.mvnbook.account</groupId> <artifactId>account-parent</artifactId> <version>1.0.0-SNAPSHOT</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>注意上述代码中依赖的type值为pom,import范围依赖由于其特殊性,一般都是指向打包类型为pom的模块。如果有多个模块,他们使用的依赖版本都是一致的,这就可以定义一个使用dependencyManagement转门管理依赖的POM,然后在各个项目中倒入这些依赖管理配置。
插件管理
Mavan提供了dependencyManag元素帮助管理依赖,类似地,Maven也提供了pluginManag元素帮助管理插件。在该元素中的配置并不会造成实际的插件调用行为,当POM中配置了真正的plugin元素,并且其groupId和artifactId与pluginManagement中配置的插件匹配时,pluginManagement的配置才会影响实际的插件行为。
//account-parent配置pluginManagement后的pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <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>4.1.7.RELEASE</springframework.version> <junit.version>4.12</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> <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <configuration> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </pluginManagement> </build> </project>account-email和account-persist可以完全地移除关于maven-compiler-plugin和maven-rescources-plugin的配置,但它们仍能使用这两个插件的服务,前一插件开启了Java 7编译支持,后一插件会使用UTF-8处理资源文件。这背后涉及很多Maven机制,首先,内置的插件绑定关系将两个插件绑定到了account-email和account-persist的生命周期上;其次,超级POM为这两个插件声明了版本;最后,account-parent中的pluginManagement对这两个插件的行为进行了配置。
当项目中的多个模块有同样的插件配置时,应当将配置移到父POM的pluginManagement元素中。即使各个模块对于同一插件的具体配置不尽相同,也应当使用父POM的pluginManagement元素统一生命擦肩的版本。甚至可以要求将所有用到的插件的版本在父POM的pluginManagement元素中声明,子模块使用插件时不配置版本信息,这么做可以同一项目的插件版本,避免潜在的插件不一致或者不稳定问题,也更易于维护。
参考:《Maven实战》第8章——徐晓斌著
相关文章推荐
- java自动生成验证码插件-kaptcha
- 【DevOps】为什么我们永远疲于奔命?
- 网络管理之IP地址篇
- 文件的读出 编辑 管理
- PostgreSQL教程(三):表的继承和分区表详解
- Lua面向对象之类和继承浅析
- 浅析Ruby中继承和消息的相关知识
- 加载flash9.ocx出现错误的解决方法
- jquery实现的代替传统checkbox样式插件
- SQL Server 2008 R2 应用及多服务器管理
- 10款新鲜出炉的 jQuery 插件(Ajax 插件,有幻灯片、图片画廊、菜单等)
- 设计引导--一个鸭子游戏引发的设计理念(多态,继承,抽象,接口,策略者模式)
- 推荐40个非常优秀的jQuery插件和教程【系列三】
- C++实现不能被继承的类实例分析
- VC下通过系统快照实现进程管理的方法
- Node.js插件的正确编写方式
- 推荐十款免费 WordPress 插件
- js继承 Base类的源码解析
- Javascript 面向对象 继承
- JavaScript 继承使用分析