`

maven日记(五):聚合与继承

阅读更多

maven的聚合特性能够把项目的各个模块聚合在一起构建,而maven的集成特性则能够帮助抽取各个模块相同的依赖和插件等配置,在简化POM的同时,还能够促进各个模块配置的一致性。

>> 聚合的例子:

<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.juvenxu.mvnbook.account</groupId>
    <artifactId>account-aggregator</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <name>Account Aggregator</name>
    <modules>
        <module>account-email</module>
        <module>account-persist</module>
        <module>account-parent</module>
    </modules>
</project>

下面是截图:


 

上述POM依旧使用账户注册服务共同的groupId:com.juvenxu.mvnbook.account,artifactId为独立的account-aggregator,版本也与其他两个模块一致。这里有个特殊的地方就是packaging为pom,对于聚合模块来说,打包方式必须为packaging为pom,否则无法构建。

POM的modules元素指定任意数量的module来实现模块的聚合,这里每个model的值都是一个相对于当前POM的相对目录,注意,为了方便快速定位,模块所处的目录名称应该与其artifactId一致,不过这个不是必须的,用户可以将account-emails项目放到email-account/目录下,这时候。module的值为email-account了。

一般都会把聚合模块放在顶层,然后子模块放到聚合模块POM目录的子目录下,这样便于查找,就像上面的那样,不过你也可以平行放置,这时候,聚合模块的POM配置就要改了:

<modules>
    <module>../account-email</module>
    <module>../account-persist</module>
    <module>../account-parent</module>
</modules

这样够清楚了吧。

在聚合模块上运行mvn clean install,会先解析聚合模块的POM、分析要构建的模块,并计算出一个反应堆构建顺序(Reactor Build Order),然后根据这个顺序依次构建各个模块。反应堆是所有模块组成的一个构建结构。从构建的输出来看,显示的是各个模块的名称(也就是POM定义中的name的值),而不是artifactiId,所以你定义POM的时候一定要写好name。

>> 继承的例子:

仔细观察可以发现account-email跟account-persist模块有很多重复的配置,比如groupId,version,dependency,plugin等等。可以定义个account-parent模块,定义它们的公共属性,然后让这两个模块继承自account-parent父模块:

<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/maven-v4_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>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>
            ...
        </dependencies>
    </dependencyManagement>
    <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>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

然后下面是account-email定义:

<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
 
    <parent>
        <groupId>com.juvenxu.mvnbook.account</groupId>
        <artifactId>account-parent</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <relativePath>../account-parent/pom.xml</relativePath>
    </parent>
 
    <artifactId>account-persist</artifactId>
    <name>Account Persist</name>
 
    <properties>
        <dom4j.version>1.6.1</dom4j.version>
    </properties>
 
    <dependencies>
        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>${dom4j.version}</version>
        </dependency>
        ...
    </dependencies>
 
    <build>
        <testResources>
            <testResource>
                <directory>src/test/resources</directory>
                <filtering>true</filtering>
            </testResource>
        </testResources>
    </build>
</project>

下面列出在maven中可以被继承的POM元素:

* groupId:项目组ID,项目坐标的核心元素

* version:项目版本,项目坐标的核心元素

* description:项目的描述信息

* organization:项目的组织信息

* inceptionYear:项目的创始年份

* url:项目的URL地址

* developers:项目的开发者信息

* contributors:项目的贡献者信息

* distributionManagement:项目的部署信息

* issueManagement:项目的缺陷跟踪系统信息

* ciManagement:项目的持续集成系统信息

* scm:项目的版本控制系统信息

* mailingLists:项目的邮件列表信息

* properties:自定义的Maven属性

* dependencies:项目的依赖配置

* dependencyManagement:项目的依赖管理配置

* repositories:项目的仓库配置

* build:包括项目的源码输出目录配置、输出目录配置、插件配置、插件管理配置等

* reporting:包括项目的报告输出目录配置、报告插件配置等

现在是时候来解释下父pom.xml文件中定义的dependencyManagement的含义了:Maven提供的dependencyManagement元素既能让子模块继承到父模块的依赖配置,又能保证子模块依赖使用的灵活性。在dependencyManagement元素下的依赖声明不会引入实际的依赖,不过它能约束dependencies下的依赖使用,例如可用在dependencyManagement配置这个:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${springframework.version}</version>
</dependency>

而在子pom.xml中只需要groupId和artifactId即可引入正确的依赖包,这样做可用消除各个子模块引入jar包的版本不一致的问题,还有如果是junit的test的scope依赖,也会被继承下来,也就是说子模块中只要groupId和artifactId即可了。

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
</dependency>

还有个import依赖范围比较特殊,这个东东只有在dependencyManagement元素下才有用,使用该范围的依赖通常指向一个POM,作用是将目标POM中的dependencyManagement配置导入并合并到当前POM的dependencyManagement元素中。除了复制和继承,还可以用import。

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.juven...</groupId>
                <artifactId>account-parent</artifactId>
                <version>1.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
</dependencyManagement>

注意上面的type为pom,import范围依赖由于其特殊性,一般都指向打包类型为pom的模块。

>> 插件管理pluginManagement:

类似于dependencyManagement元素管理依赖,maven提供了pluginManagement管理插件,也就是说该元素中配置的依赖不会造成实际的插件调用行为,但pom中配置真正的plugin元素的时候,并且其groupId和artifactId与pluginManagement中配置的插件匹配的时候,才会影响实际的插件行为。这个元素基本都是在父POM中定义,然后子模块去继承就可以了。

>> 反应堆的构建顺序:

反应堆(Reactor)是指所有模块组成的一个构建结构,对于单个模块来讲,反应堆就是该模块本身,但对于多模块项目来说,反应堆就包含各个模块之间继承与依赖的关系,从而能够自动计算出合理的模块构建顺序。

实际的构建顺序是这样的:Maven按顺序读取POM,如果该POM没有依赖模块,那么就构建该模块,否则就先构建其依赖模块,如果该依赖还有其他依赖,则进一步先构建其他依赖。

>> 裁剪反应堆:

maven提供很多命令支持裁剪反应堆,输入mvn -h查看选项:

* -am或者–also-make:同时构建所列模块的依赖模块

* -amd或者-also-make-dependents:同时构建依赖于所列模块的模块

* -pl或者–projects <args> 构建指定模块,模块间用逗号隔开

* -rf或 -resume-from <args> 从指定的模块开始构建反应堆

# mvn clean install -pl account-email,account-persist

# mvn clean install -pl account-email -am

# mvn clean install -pl account-parent -amd

# mvn clean install -rf account-email

# mvn clean install -pl account-parent -amd -rf account-email

 

本人博客已搬家,新地址为:http://yidao620c.github.io/

  • 大小: 84.6 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics