maven-聚合与继承
1、聚合-方便快速构建项目
多个maven模块要构建需要分别执行一次maven构建命令,怎样只执行一次构建命令就构建多个maven模块呢?maven提供了聚合模块可以满足一次运行,构建多模块的要求
2、继承-消除重复配置,统一管理
多个maven模块中的pxm.xml有很多相同的配置,如果简化配置?maven提供了继承机制,抽出重复的配置,统一依赖管理和插件管理
maven工程隐式的继承超级POM,超级POM如下:
<?xml version="1.0" encoding="UTF-8"?> <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <!-- START SNIPPET: superpom --> <project> <modelVersion>4.0.0</modelVersion> <repositories> <repository> --中央仓库 <id>central</id> <name>Central Repository</name> <url>https://repo.maven.apache.org/maven2</url> <layout>default</layout> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> --中央插件仓库 <id>central</id> <name>Central Repository</name> <url>https://repo.maven.apache.org/maven2</url> <layout>default</layout> <snapshots> <enabled>false</enabled> </snapshots> <releases> <updatePolicy>never</updatePolicy> </releases> </pluginRepository> </pluginRepositories> <build> --在子maven工程中设定相同的标签元素的值,则覆盖父POM的标签元素的值 <directory>${project.basedir}/target</directory> --项目主输出目录 <outputDirectory>${project.build.directory}/classes</outputDirectory> --主代码输出目录 <finalName>${project.artifactId}-${project.version}</finalName> --最终构建的名称格式 <testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory> --测试代码输出目录 <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory> --主源码目录 <scriptSourceDirectory>${project.basedir}/src/main/scripts</scriptSourceDirectory> --脚本源码目录 <testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory> --测试源码目录 <resources> <resource> --主资源目录 <directory>${project.basedir}/src/main/resources</directory> </resource> </resources> <testResources> --测试资源目录 <testResource> <directory>${project.basedir}/src/test/resources</directory> </testResource> </testResources> <pluginManagement> --申明核心插件,设定了版本 <!-- NOTE: These plugins will be removed from future versions of the super POM --> <!-- They are kept for the moment as they are very unlikely to conflict with lifecycle mappings (MNG-4453) --> <plugins> <plugin> <artifactId>maven-antrun-plugin</artifactId> <version>1.3</version> </plugin> <plugin> <artifactId>maven-assembly-plugin</artifactId> <version>2.2-beta-5</version> </plugin> <plugin> <artifactId>maven-dependency-plugin</artifactId> <version>2.8</version> </plugin> <plugin> <artifactId>maven-release-plugin</artifactId> <version>2.3.2</version> </plugin> </plugins> </pluginManagement> </build> <reporting> <outputDirectory>${project.build.directory}/site</outputDirectory> </reporting> <profiles> <!-- NOTE: The release profile will be removed from future versions of the super POM --> <profile> <id>release-profile</id> <activation> <property> <name>performRelease</name> <value>true</value> </property> </activation> <build> <plugins> <plugin> <inherited>true</inherited> <artifactId>maven-source-plugin</artifactId> <executions> <execution> <id>attach-sources</id> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> <plugin> <inherited>true</inherited> <artifactId>maven-javadoc-plugin</artifactId> <executions> <execution> <id>attach-javadocs</id> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> <plugin> <inherited>true</inherited> <artifactId>maven-deploy-plugin</artifactId> <configuration> <updateReleaseInfo>true</updateReleaseInfo> </configuration> </plugin> </plugins> </build> </profile> </profiles> </project> <!-- END SNIPPET: superpom -->
以下元素可从超级POM获者其它的POM文件继承:
3、聚合和继承的关系
对于聚合模块,它知道有哪些被聚合的模块,但那些被聚合的模块不知道聚合模块的存在。
对于继承关系的父POM,它不知道有哪些子模块继承它,但那些子模块知道自己继承的父POM
相同点:聚合POM和继承关系中的父POM的packaging必须是pom,
聚合模块和继承关系中到的父模块除了pom之外都没有实际内容
在实际项目中,通常聚合模块和继承关系中到的父模块是同一个,这主要是为了方便
4、maven聚合工程(+父工程)
两种常用的多模块的maven工程目录结构:
其中,parent既是聚合工程,也是父工程。
- 新建聚合工程:略
- parent模块的pom.xml文件
<?xml version="1.0" encoding="UTF-8"?> <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.cn</groupId> <artifactId>parent</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>../common</module> --被聚合的common模块 <module>../mananger</module> </modules> <name>parent</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> --定义属性的值,后续可以被引用 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> <spring-version>3.2.2.RELEASE</spring-version> </properties> <dependencies> --需要引入的依赖 <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> --申明依赖,但实际不会被引入 <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring-version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring-version}</version> </dependency> </dependencies> </dependencyManagement> <build> <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --> --申明插件,但实际不会被引入 <plugins> <plugin> <artifactId>maven-clean-plugin</artifactId> <version>3.0.0</version> </plugin> <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging --> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>3.0.2</version> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.7.0</version> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.20.1</version> </plugin> <plugin> <artifactId>maven-jar-plugin</artifactId> <version>3.0.2</version> </plugin> <plugin> <artifactId>maven-install-plugin</artifactId> <version>2.5.2</version> </plugin> <plugin> <artifactId>maven-deploy-plugin</artifactId> <version>2.8.2</version> </plugin> </plugins> </pluginManagement> </build> </project>
- 子模块manager的pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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"> <parent> --配置继承父工程 <artifactId>parent</artifactId> <groupId>com.cn</groupId> <version>1.0-SNAPSHOT</version> <relativePath>../parent/pom.xml</relativePath> --父工程pom.xml的相对位置,未配置则默认为上一层目录下 </parent> <modelVersion>4.0.0</modelVersion> <artifactId>mananger</artifactId> --省略了版本和组id,因为从父pom中继承了 <packaging>war</packaging> <name>mananger Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> </properties> <dependencies> <dependency> --实际引入了父pom中申明的jar包,只需指定id <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> --实际引入父pom中申明的插件 <artifactId>maven-compiler-plugin</artifactId> <version>3.7.0</version> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> </plugins> </build> </project>
- 聚合工程执行构建项目命令,执行过程?
Maven按序读取POM,如果该POM没有继承模块,就构建该模块,否则就先构建其继承的模块,如果该继承的模块还继承其它模块,则进一步先构建继承的模块。在此过程中,构建过的模块不再构建。
假设A项目聚合了B、C项目,B、C项目继承D项目,D继承E,则构建顺序为:A、E、D、B、C