参考: https://www.iteye.com/blog/elim-2055745
maven基础回顾
maven通过groupdId:artifactId:version
三者来唯一确定一个项目, 因此在pom.xml文件中这三者是必须配置的
<groupId>org.example</groupId>
<artifactId>demo-web</artifactId>
<version>1.0-SNAPSHOT</version>
maven命令
参考: https://blog.csdn.net/shenzhou_yh/article/details/105988113
常见参数
-D D代表Property属性 定义一个property, 示例$mvn clean package -Dmaven.test.skip=true
-P P代表Profile, 激活指定的profile文件列表, 以逗号隔开, 示例$mvn clean package -P prod
-f 使用指定的pom文件替换当前的pom文件
-ff 最快失败模式, 多模块构建时, 遇到第一个失败的构建时停止
-e 显示详细错误信息
-am 构建指定模块, 同时构建指定模块依赖的其他模块
-amd 构建指定模块, 同时构建依赖于指定模块的其他模块
-pl 手动选择要构建的项目, 项目间以逗号隔开
maven中的属性
在pom.xml中可以使用${propertyName}来引用属性, propertyName有以下几种形式:
- env.propertyName:环境变量,比如当前系统的环境变量${env.PATH}。
- project.propertyName:当前这个pom.xml中project根元素下面的子元素的值。比如${project.version}。
- settings.propertyName:Maven本地配置文件settings.xml或本地Maven安装目录下的settings.xml文件根元素settings下的元素。比如${settings.localRepository}
- java的系统属性,所有在java中使用java.lang.System.getProperties()能够获取到的属性都可以在pom.xml中引用,比如${java.home}。
- pom.xml中properties元素下面的子元素作为属性。假如在pom.xml中有如下一段代码
,那么我们就可以使用${hello.world}引用到对应的helloWorld。helloWorld
资源文件的打包
maven允许资源文件中的值在编译时动态指定, 建立文件时以${propertyName}的形式指定. maven这种动态替换属性值的功能默认是关闭的,如果要打开的话需要在项目的pom.xml文件中指定filtering的值为true,默认是false
示例场景: 当项目资源路径下有excel等模板文件时, 若开启了filter后, 打包会将模板文件中的${变量}替换掉, 影响模板的正常功能, 因此需要配置将相关文件的filter设为false
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<targetPath>${dist.path}</targetPath>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<targetPath>${dist.path}</targetPath>
<filtering>false</filtering>
<includes>
<include>excel/**</include>
<include>es/**</include>
</includes>
</resource>
</resources>
</build>
多模块之间的关系
继承
形成继承关系需要在子项目pom.xml中定义指向父项目的parent
标签
继承的作用:
和java里面的继承类似,子pom.xml会完全继承父pom.xml中所有的元素,而且对于相同的元素,一般子pom.xml中的会覆盖父pom.xml中的元素,但是有几个特殊的元素它们会进行合并而不是覆盖。这些特殊的元素是:
- dependencies
- developers
- contributors
- plugin列表,包括plugin下面的reports
- resources ```json 示例: 工程结构如下, B在A项目目录下 projectA —projectB ——————-projectB的pom.xml———————- <?xml version=”1.0” encoding=”UTF-8”?>
注意: 若A与B在同级目录, 须通过relativePath指定父工程的pom.xml位置, relativePath指的是目录路径 —projectA —projectB ——————-projectB的pom.xml———————- <?xml version=”1.0” encoding=”UTF-8”?>
<parent>
<artifactId>projectA</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../projectA/pom.xml</relativePath>
</parent>
<artifactId>projectB</artifactId>
<a name="pd5GF"></a>
#### 聚合
示例: 工程结构如下, B在A项目目录下
<br />projectA
<br />--projectB<br />如示例的工程结构, B项目聚合到A项目, 可以说B是A的子模块, A是被聚合的项目, 也是聚合的主体
形成聚合关系需要:
1. 修改被聚合项目的pom.xml中的packaging元素的值为pom
1. 在**主体项目**pom.xml中定义**聚合项目**为`module`
聚合的作用:<br />在主体项目目录下使用maven命令时, 这些命令都会在聚合项目下执行.
```json
示例: 工程结构如下, B在A项目目录下
projectA
--projectB
-------------projectA的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>org.example</groupId>
<artifactId>projectA</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>projectB</module>
</modules>
注意: 若A与B在同级目录, 须在module中指定正确的目录路径
--projectA
--projectB
-------------projectA的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>org.example</groupId>
<artifactId>projectA</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>../projectB</module>
</modules>
</project>
Reactor
参考: https://blog.csdn.net/weixin_30408309/article/details/94972603
对于多模块的项目, maven的Reactor包含了各模块之间继承与依赖的关系, 从而能自动计算出合理的模块构建顺序.
- 当需要构建整个项目时, 直接在项目目录下执行maven命令
- 当只需要构建某个模块时, 就需要对反应堆进行裁剪
示例: 以下命令表示构建模块A并且构建A依赖的其他模块
mvn clean package -Dmaven.test.skip=true -pl moduleA -am
依赖
<dependency>
<groupId>xxx</groupId>
<artifactId>xxx</artifactId>
<version>xxx</version>
<type>jar</type> // 依赖项目的打包类型, 默认jar
<scope>compile</scope>
// 表示依赖项目的作用范围:
- compile, 默认值, 表示所有情况有效, 且可传递
- provided, 测试和编译有效, 运行时将有jdk或容器提供, 不可传递
- runtime, 运行时必须
- test, 测试时必须
- system, 类似provided, 结合systemPath使用
<systemPath></systemPath> // 指定依赖的jar包在系统的绝对路径, 只在scope为system时才可以使用
<optional></optional> // 可选的
<exclusions> // 排除依赖
<exclusion>
<artifactId></artifactId>
<groupId></groupId>
</exclusion>
</exclusions>
</dependency>
补充: 只能有一个父工程, 其他依赖可以通过import方式导入
<!--springboot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
多模块聚合工程的构建
由上面的总结, 一般多模块项目都会定义成父子以及聚合结构, 其中
- 父子结构: 父pom.xml中统一定义依赖版本以及插件版本, 子工程无需对版本进行管理
聚合结构: 用于构建项目时, 子工程一并构建, 但此时若要单独构建子工程, 则需要配合-pl am命令食用
示例项目结构:
demo-cloud
--demo-common // 定义通用实体
--demo-web // 定义web接口, 依赖于demo-common
demo-cloud父工程的pom.xml ```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">
4.0.0 org.example demo-cloud pom 1.0-SNAPSHOT demo-web demo-common 1.8 ${basedir}/../target 1.8 1.8 UTF-8 1.0-SNAPSHOT <dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>demo-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.example</groupId>
<artifactId>demo-web</artifactId>
<version>${project.version}</version>
</dependency>
<!--springboot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.33</version>
</dependency>
</dependencies>
</dependencyManagement>
demo-web工程的pom.xml
```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>
<parent>
<artifactId>demo-cloud</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>demo-web</artifactId>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>demo-common</artifactId>
</dependency>
<!--springbootTest-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
demo-common工程的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>
<parent>
<artifactId>demo-cloud</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>demo-common</artifactId>
</project>
此时若要单独构建demo-web(以及需要将依赖的demo-common打包进来), 在demo-cloud目录下命令如下
\demo-cloud> $mvn clean package -Dmaven.test.skip=true -pl ./demo-web -am