• Maven学习(五)-- 聚合与继承


    标签(空格分隔): 学习笔记


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

    account-persist模块

    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.park.mvnDemo.account</groupId>
        <artifactId>account-persist</artifact>
        <name>Account Persist</name>
        <version>1.0.0-SNAPSHOT</version>
        
        <dependencies>  
            <dependency>
                <groupId>dom4j</groupId>
                <artifactId>dom4j</artifact>
                <version>1.6.1</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-beans</artifact>
                <version>2.5.6</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifact>
                <version>2.5.6</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifact>
                <version>2.5.6</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifact>
                <version>4.7</version>
                <scope>test</scope>
            </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.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>
        </build>
    </project>
    

    account-persist模块还需要一个SpringFramework的配置文件,位于src/main/resources目录:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
        
        <bean id="propertyConfigure" class="org.springframework.beans.factory.config.PropertyPlaceholderconfigure">
            <property name="location" value="classpath:account-service.properties"/>
        </bean>
        
        <bean id="accountPersistService" class="com.park.mvnDemo.account.persist.AccountPersistServiceImpl">
        <property name="file" value="${persist.file}"/>
        </bean>
    <beans>
    

    聚合

    我们想要一次构建两个项目,而不是到两个模块的目录下分别执行mvn命令 -- Maven的聚合就是为该需求服务的。

    为了能够使用一条命令就能构建account-emailaccount-persist两个模块,需要创建一个额外的名为account-aggregator的模块,然后通过该模块构建整个项目的所有模块。

    account-aggregator也有它自己的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.park.mvnDemo.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>
        </modules>
    </project>
    

    在上面的xml文件中,packaging的方式为pom。对于聚合模块来说,其打包方式必须为pom,否则无法构建!

    • modules: 这里是实现聚合的最核心的配置,可以声明任意数量的module元素来实现元素的聚合;
    • 其中,每个module的值为当前POM的相对路径;
    • 如:当前POM位于D:m2codeaccount-aggregatorpom.xml, 另有一个项目A位于D:m2codeaccount-aggregatoraccount-email/,一个项目B位于D:m2code-aggregatoraccountaccount-persist/,与上面的module值相对应。
    • 为了方便用户构建项目,通常将聚合模块放在项目目录的最顶层,其他模块则作为聚合模块的子目录存在。

    继承

    在我们已经聚合的项目中,有很多重复的配置,有相同的groupId和version,有相同的spring-core, spring-beans, spring-context和juit依赖,造成大量的浪费也会引发问题,所以如何使用继承机制来统一配置这些重复的信息,做到”一处声明,处处使用“呢?

    思路:创建POM的父子结构,在父POM中声明一些配置供子POM继承、

    父模块

    account-aggregator目录下创建POM的父目录account-parent,内部的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.park.mvnDemo.account</groupId>
        <artifactId>account-parent</artifactId>
        <version>1.0.0</version>
        <packaging>dom<packaging>
        <name>Account Parent</name>
    </project>
    

    作为父模块的POM,其打包类型也是只能为pom。

    由于父模块只是为了帮助消除配置的重复,因此她本身不包含除POM外的项目文件,也就不需要src/main/java之类的文件了。

    子模块 -- 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.park.mvnDemo.account</groupId>
            <artifactId>account-parent</artifactId>
            <version>1.0.0</version>
            <relativePath>../account-parent/pom.xml</relativePath>
        </parent>
        
        <artifactId>account-email</artifactId>
        <name>Account Email</name>
        
        <dependencies>
        ...
        </dependencies>
        
        <build>
            <plugins>
            ...
            </plugins>
        </build>
    </project>
    

    (子模块account-persist的pom配置与之类似,不再赘述)

    聚合模块 -- account-aggregator

    <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.park.mvnDemo.account</groupId>
        <artifactId>account-aggregator</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <packaging>dom</packaging>
        <name>Account Aggregator</name>
        <modules>
            <module>account-parent</module>
            <module>account-email</module>
            <module>account-persist</module>
        </modules>
    </project>
    

    可继承的POM元素

    • groupId: 项目组ID,项目坐标的核心坐标;
    • version: 项目版本,项目坐标的核心坐标;
    • description: 项目的描述信息;
    • organization: 项目的组织信息;
    • inceptionYear: 项目的创始年份;
    • url: 项目的URL地址;
    • developers: 项目的开发者信息;
    • contributors: 项目的贡献值和信息;
    • distributionManagement: 项目的部署配置;
    • issueManagement: 项目的缺陷跟踪系统;
    • ciManagement: 项目的持续集成系统信息;
    • scm: 项目的版本控制系统信息;
    • mailingLists: 项目的邮件列表信息;
    • properties: 自定义的Maven属性;
    • dependencies: 项目的依赖配置;
    • dependencyManagement: 项目的依赖管理配置;
    • repositories: 项目的仓库配置;
    • build: 包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等;
    • reporting: 包括项目的报告输出目录配置、报告插件配置等。

    依赖管理

    dependencies可以使得子模块继承父模块依赖的插件,同时dependencyManagement元素又能保证子模块使用的灵活性。在dependencyManagement元素下的声明不会引入实际的依赖,不过它能够约束dependencies下的依赖使用。
    示例:

    (一) 在account-parent中配置dependencyManagement元素

    <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.park.mvnDemo.account</groupId>
        <artifactId>account-parent</artifactId>
        <version>1.0.0_SNAPSHOT</version>
        <packaging>dom</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</artifact>
                    <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>
        </depedencyManagement>
    </project>
    

    (二) 继承了dependencyManagement的account-email POM

    <properties>
        <javax.mail.version>1.4.1</javax.mail.version>
        <greenmail.version>1.3.1b</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>
    

    如果不声明某个依赖,那这个依赖就不会被引入。

    插件管理

    Maven提供了pluginManagement元素来管理插件。在该元素中配置的依赖不会造成实际的插件调用行为,当POM中配置了真正的plugin元素,并且其groupId和artifactId与pluginManagement中配置的插件相匹配时,pluginManagement的配置才会影响实际的插件行为。

    (一) 在父POM中配置pluginManagement

    <build>
        <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>
                        </exeuction>
                    </executions>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
    

    (二) 在子模块中配置相应的插件

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

    聚合与继承的关系

    • 聚合是为了方便快速构件项目。对于聚合模块来说,它知道有哪些被聚合的模块,但那些模块不知道这个聚合模块的存在;
    • 继承是为了消除重复配置。对于继承关系的父POM来说,它不知道有哪些子模块继承于它,但是子模块必须知道自己的父POM是什么。

    在实际的项目中,一个POM可以既是聚合POM,又是父POM。
    如果父模块位于子模块们的上级,则不需要再额外配置relativePath,因为Maven默认能识别父模块的位置。

    反应堆(Reactor)

    在一个多模块的Maven项目中,反应堆是指所有模块组成的一个构件结构。包含了各模块之间继承于依赖的关系,从而能够自动计算出合理的模块构件顺序。

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

    模块间的依赖关系会将反应堆构成一个有向无环图(DAG: Directed Acyclic Graph),各个模块是该图的节点,依赖关系构成了有向边。

    裁剪反应堆

    当用户并不想构建整个项目的时候,就需要实时地裁剪反应堆。
    Maven提供很多命令行支持裁剪反应堆:

    • -am, --alsomake: 同时构建所列模块的依赖模块模块;

    • -amd, --also-make-dependents: 同时构建依赖于所列模块的模块;

    • -pl, --projects<arg>: 构建指定模块,模块间用逗号分割;

    • -rf, -resume-from<arg>: 从指定的模块回复反应堆。

      $ mvn clean install
      \Output: Account Aggregator, Account Parent, Account Email, Account Persist
      $ mvn clean install -pl account-email,account-persist
      \Output: Account Email, Account Persist
      $ mvn clean install -pl account-email -am
      \Output: Account Parent, Account Email
      $ mvn clean install -pl account-parent -amd
      \Output: Account Parent, Account Email, Account Persist
      $ mvn clean install -rf account-email
      \Output: Account Email, Account Persist
      $ mvn clean install -pl account-parent -amd -rf account-email
      \Output: Account Email, Account Persist

  • 相关阅读:
    绍一集训Round#2
    CF 799B T-shirt buying
    Luogu P2827 蚯蚓
    Luogu P4053 [JSOI2007]建筑抢修
    【LGR-049】洛谷7月月赛
    浅谈可持久化数据结构
    CF 888E Maximum Subsequence
    在平衡树的海洋中畅游(三)——Splay
    浅谈单调栈/队列
    CF 859E Desk Disorder
  • 原文地址:https://www.cnblogs.com/little-YTMM/p/5990696.html
Copyright © 2020-2023  润新知