Maven 自动化的构建工具详解

文章目录

Maven 自动化的构建工具

第一章 Maven简介

1.1 软件开发中的阶段

需要分析: 分析项目具体完成的功能,有什么要求, 具体怎么实现。

设计阶段:根据分析的结果, 设计项目的使用什么技术, 解决难点。

开发阶段:编码实现功能。 编译代码。自我测试

测试阶段:专业的测试人员,测整个项目的功能十分符合设计要求。出一个测试报告。

项目的打包,发布阶段: 给用户安装项目

1.2 Maven能做什么

1)项目的自动构建,帮助开发人员做项目代码的编译,测试, 打包,安装,部署等工作。

2)管理依赖(管理项目中使用的各种jar包)。

​ 依赖:项目中需要使用的其他资源, 常见的是jar 。 比如项目要使用mysql驱动。我们就说项目依赖mysql驱动。

1.3 没有使用Maven怎么管理依赖

管理jar ,需要从网络中单独下载某个jar

需要选择正确版本

手工处理jar文件之间的依赖。 a.jar里面要使用b.jar的类。

1.4 什么是Maven

maven是apache基金会的开源项目,使用java语法开发。 Maven 这个单词的本意是:专家,内行。读音是['meɪv(ə)n] 或 ['mevn]。

maven是项目的自动化构建工具。 管理项目的依赖。

1.5 Maven中的概念

①POM
②约定的目录结构
③坐标
④依赖管理
⑤仓库管理
⑥生命周期
⑦插件和目标
⑧继承
⑨聚合

1.6 Maven特点

Maven 具有以下特点:

  1. 设置简单。
  2. 所有项目的用法一致。
  3. 可以管理和自动进行更新依赖。
  4. 庞大且不断增长的资源库。
  5. 可扩展,使用 Java 或脚本语言可以轻松的编写插件。
  6. 几乎无需额外配置,即可立即访问新功能。
  7. 基于模型的构建:Maven 能够将任意数量的项目构建为预定义的输出类型,例如 JAR,WAR。
  8. 项目信息采取集中式的元数据管理:使用与构建过程相同的元数据,Maven 能够生成一个网站(site)和一个包含完整文档的 PDF。
  9. 发布管理和发行发布:Maven 可以与源代码控制系统(例如 Git、SVN)集成并管理项目的发布。
  10. 向后兼容性:您可以轻松地将项目从旧版本的 Maven 移植到更高版本的 Maven 中。
  11. 并行构建:它能够分析项目依赖关系,并行构建工作,使用此功能,可以将性能提高 20%-50%。
  12. 更好的错误和完整性报告:Maven 使用了较为完善的错误报告机制,它提供了指向 Maven Wiki 页面的链接,您将在其中获得有关错误的完整描述。

1.7 Maven工具的获取和安装

地址: http://maven.apache.org/ 从中下载 .zip文件。 使用的 apache-maven-3.3.9-bin.zip

安装:

  1. 确定JAVA_HOME 指定jdk的安装目录, 如果没有JAVA_HOME, 需要在windows的环境变量中创建JAVA_HOME, 它的值是jdk的安装目录

  2. 解压缩 apache-maven-3.3.9-bin.zip ,把解压后的文件放到一个目录中。

    目录的路径不要有中文, 不要有空格。

  3. 把maven安装目录中下的bin的路径添加到path中

  4. 测试maven的安装。 在命令行执行 mvn -v

    C:\Users\NING MEI>mvn -v
    Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-11T00:41:47+08:00)
    Maven home: D:\tools\apache-maven-3.3.9\bin\..
    Java version: 1.8.0_101, vendor: Oracle Corporation
    Java home: C:\Program Files\Java\jdk1.8.0_101\jre
    Default locale: zh_CN, platform encoding: GBK
    OS name: "windows 10", version: "10.0", arch: "amd64", family: "dos"
    

maven解压后的目录结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1gG5I55k-1634806280178)(images/image-20201015162301261.png)]

maven的其他安装方式:

  1. 确定JAVA_HOME是否有效

  2. 在环境变量中,创建一个叫做M2_HOME (或者MAVEN_HOME) ,它的值是maven的安装目录

    M2_HOME=D:\tools\apache-maven-3.3.9

  3. 在path环境变量中,加入 %M2_HOME%\bin

  4. 测试maven的安装,在命令行执行 mvn -v

    C:\Users\NING MEI>mvn -v
    Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-11T00:41:47+08:00)
    Maven home: D:\tools\apache-maven-3.3.9\bin\..
    Java version: 1.8.0_101, vendor: Oracle Corporation
    Java home: C:\Program Files\Java\jdk1.8.0_101\jre
    Default locale: zh_CN, platform encoding: GBK
    OS name: "windows 10", version: "10.0", arch: "amd64", family: "dos"
    

1.8 Maven项目的构建和测试

1、构建项目

查看 helloMaven 项目的 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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>net.biancheng.www</groupId>
    <artifactId>helloMaven</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>helloMaven</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

​ 从以上配置可知,Maven 已经添加了 Junit 作为该项目的测试框架,且 Maven 也在项目中自动生成了一个源码文件 App.java 和一个测试文件 AppTest.java 。

​ 打开命令行窗口,跳转到 D:\maven\helloMaven 目录,执行以下 mvn 命令,对该项目进行构建。

mvn clean package

​ 命令执行结果如下:

[INFO] Scanning for projects...
[INFO]
[INFO] --------------------< net.biancheng.www:helloMaven >--------------------
[INFO] Building helloMaven 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ helloMaven ---
[INFO] Deleting D:\maven\helloMaven\target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ helloMaven ---
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory D:\maven\helloMaven\src\main\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ helloMaven ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding GBK, i.e. build is platform dependent!
[INFO] Compiling 1 source file to D:\maven\helloMaven\target\classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ helloMaven ---
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory D:\maven\helloMaven\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ helloMaven ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding GBK, i.e. build is platform dependent!
[INFO] Compiling 1 source file to D:\maven\helloMaven\target\test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ helloMaven ---
[INFO] Surefire report directory: D:\maven\helloMaven\target\surefire-reports
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-junit3/2.12.4/surefire-junit3-2.12.4.pom
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-junit3/2.12.4/surefire-junit3-2.12.4.pom (1.7 kB at 1.3 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-junit3/2.12.4/surefire-junit3-2.12.4.jar
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-junit3/2.12.4/surefire-junit3-2.12.4.jar (26 kB at 51 kB/s)
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running net.biancheng.www.AppTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.007 sec
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ helloMaven ---
[INFO] Building jar: D:\maven\helloMaven\target\helloMaven-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  4.775 s
[INFO] Finished at: 2021-03-02T17:20:15+08:00
[INFO] ------------------------------------------------------------------------

项目构建完成后,在该项目根目录中生成了一个名为 target 的目录,该目录包含以下内容。

image-20211010210415613

说明:

  • Maven 命令中包含了两个命令:clean 和 package,其中 clean 负责清理 target 目录,package 负责将项目构建并打包输出为 jar 文件。
  • classes:源代码编译后存放在该目录中。
  • test-classes:测试源代码编译后并存放在该目录中。
  • surefire-reports:Maven 运行测试用例生成的测试报告存放在该目录中。
  • helloMaven-1.0-SNAPSHOT.jar:Maven 对项目进行打包生成的 jar 文件。

打开命令控制台,跳转到 D:\maven\helloMaven\target\classes 目录,执行 Java 命令

java net.biancheng.www.App

执行结果如下。

Hello World!

2、测试项目

下面我们介绍如何在 Maven 项目中添加其他的 Java 文件,并进行测试。

打开 D:\maven\helloMaven\src\main\java\net\biancheng\www 文件夹,在其中创建一个名为 Util.java 的文件。

package net.biancheng.www;/*** Maven 项目中添加的自定义java类** @author 编程帮 www.biancheng.net*/public class Util {    public static void printMessage(String message) {        System.out.println(message);    }}

更新 App 类,调用 Util 类中的 printMessage() 方法,代码如下。

package net.biancheng.www;/*** @author 编程帮 www.biancheng.net*/public class App {    public static void main(String[] args) {        Util.printMessage("编程帮欢迎您,网址:www.biancheng.net");    }}

打开命令行窗口,跳转到 D:\maven\helloMaven 目录,并执行如下 Maven 命令,对项目进行编译。

mvn clean compile                                                                                  

命令执行结果如下。

[INFO] Scanning for projects...[INFO][INFO] --------------------< net.biancheng.www:helloMaven >--------------------[INFO] Building helloMaven 1.0-SNAPSHOT[INFO] --------------------------------[ jar ]---------------------------------[INFO][INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ helloMaven ---[INFO] Deleting D:\maven\helloMaven\target[INFO][INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ helloMaven ---[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent![INFO] skip non existing resourceDirectory D:\maven\helloMaven\src\main\resources[INFO][INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ helloMaven ---[INFO] Changes detected - recompiling the module![WARNING] File encoding has not been set, using platform encoding GBK, i.e. build is platform dependent![INFO] Compiling 2 source files to D:\maven\helloMaven\target\classes[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time:  0.853 s[INFO] Finished at: 2021-03-03T09:26:29+08:00[INFO] ------------------------------------------------------------------------
java  net.biancheng.www.App                                                                                    执行结果如下。
编程帮欢迎您,网址:www.biancheng.net

第二章Maven的核心概念

2.1 约定的目录结构

maven项目使用的大多人 遵循的目录结构。 叫做约定的目录结构。

一个maven项目是一个文件夹。 比如项目叫做Hello

Hello 项目文件夹    \src    	\main				叫做主程序目录(完成项目功能的代码和配置文件)             \java          源代码(包和相关的类定义)    		 \resources	    配置文件    	\test               放置测试程序代码的(开发人员自己写的测试代码)    		 \java          测试代码的(junit)    		 \resources     测试程序需要的配置文件    \pom.xml                maven的配置文件, 核心文件

maven的使用方式:

1)maven可以独立使用: 创建项目,编译代码,测试程序,打包,部署等等

2)maven和idea一起使用:通过idea借助maven,实现编码,测试,打包等等

2.2 POM

POM: Project Object Model 项目对象模型, maven把项目当做模型处理。 操作这个模型就是操作项目。

maven通过pom.xml文件实现 项目的构建和依赖的管理。

<?xml version="1.0" encoding="UTF-8"?><!-- project是根标签, 后面的是约束文件 --><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">          <!-- pom模型的版本, 就是4.0.0 -->    <modelVersion>4.0.0</modelVersion>  <!-- 坐标 -->    <groupId>com.bjpowernode</groupId>  <artifactId>ch01-maven</artifactId>  <packaging>jar</packaging>  <version>1.0-SNAPSHOT</version>    <properties>     <java.version>1.8</java.version>     <maven.compiler.source>1.8</maven.compiler.source>     <maven.compiler.target>1.8</maven.compiler.target>  </properties>  </project>

2.3 Super POM

1)说明:

​ 无论 POM 文件中是否显示的声明,所有的 POM 均继承自一个父 POM,这个父 POM 被称为 Super POM,它包含了一些可以被继承的默认设置。

​ Maven 使用 effective pom (Super POM 的配置加上项目的配置)来执行相关任务,它替开发人员在 pom.xml 中做了一些最基本的配置。当然,开发人员依然可以根据需要重写其中的配置信息。

执行以下命令 ,就可以查看 Super POM 的默认配置。

mvn help:effective-pom

2)示例:

  1. 在 D 盘创建一个名为 maven 的目录,将 POM 示例中的 pom.xml 文件移动至该文件夹下。

  2. 打开命令行窗口,跳转到 pom.xml 所在的目录下,执行以下 mvn 命令

    mvn help:effective-pom
    
  3. Maven 将会开始执行命令并显示 effective-pom 的内容,执行结果如下。

    [INFO] Scanning for projects...[INFO][INFO] ----------------------< net.biancheng.www:maven >-----------------------[INFO] Building maven 0.0.1-SNAPSHOT[INFO] --------------------------------[ jar ]---------------------------------[INFO][INFO] --- maven-help-plugin:3.2.0:effective-pom (default-cli) @ maven ---[INFO]Effective POMs, after inheritance, interpolation, and profiles are applied:<?xml version="1.0" encoding="GBK"?><!-- ====================================================================== --><!--                                                                        --><!-- Generated by Maven Help Plugin on 2021-02-26T15:25:25+08:00            --><!-- See: http://maven.apache.org/plugins/maven-help-plugin/                --><!--                                                                        --><!-- ====================================================================== --><!-- ====================================================================== --><!--                                                                        --><!-- Effective POM for project 'net.biancheng.www:maven:jar:0.0.1-SNAPSHOT' --><!--                                                                        --><!-- ====================================================================== --><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 https://maven.apache.org/xsd/maven-4.0.0.xsd">  <modelVersion>4.0.0</modelVersion>  <groupId>net.biancheng.www</groupId>  <artifactId>maven</artifactId>  <version>0.0.1-SNAPSHOT</version>  <dependencies>    <dependency>      <groupId>junit</groupId>      <artifactId>junit</artifactId>      <version>4.9</version>      <scope>compile</scope>    </dependency>    <dependency>      <groupId>log4j</groupId>      <artifactId>log4j</artifactId>      <version>1.2.17</version>      <scope>compile</scope>    </dependency>  </dependencies>  <repositories>    <repository>      <snapshots>        <enabled>false</enabled>      </snapshots>      <id>central</id>      <name>Central Repository</name>      <url>https://repo.maven.apache.org/maven2</url>    </repository>  </repositories>  <pluginRepositories>    <pluginRepository>      <releases>        <updatePolicy>never</updatePolicy>      </releases>      <snapshots>        <enabled>false</enabled>      </snapshots>      <id>central</id>      <name>Central Repository</name>      <url>https://repo.maven.apache.org/maven2</url>    </pluginRepository>  </pluginRepositories>  <build>    <sourceDirectory>D:\maven\src\main\java</sourceDirectory>    <scriptSourceDirectory>D:\maven\src\main\scripts</scriptSourceDirectory>    <testSourceDirectory>D:\maven\src\test\java</testSourceDirectory>    <outputDirectory>D:\maven\target\classes</outputDirectory>    <testOutputDirectory>D:\maven\target\test-classes</testOutputDirectory>    <resources>      <resource>        <directory>D:\maven\src\main\resources</directory>      </resource>    </resources>    <testResources>      <testResource>        <directory>D:\maven\src\test\resources</directory>      </testResource>    </testResources>    <directory>D:\maven\target</directory>    <finalName>maven-0.0.1-SNAPSHOT</finalName>    <pluginManagement>      <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.5.3</version>        </plugin>      </plugins>    </pluginManagement>    <plugins>      <plugin>        <artifactId>maven-clean-plugin</artifactId>        <version>2.5</version>        <executions>          <execution>            <id>default-clean</id>            <phase>clean</phase>            <goals>              <goal>clean</goal>            </goals>          </execution>        </executions>      </plugin>      <plugin>        <artifactId>maven-resources-plugin</artifactId>        <version>2.6</version>        <executions>          <execution>            <id>default-testResources</id>            <phase>process-test-resources</phase>            <goals>              <goal>testResources</goal>            </goals>          </execution>          <execution>            <id>default-resources</id>            <phase>process-resources</phase>            <goals>              <goal>resources</goal>            </goals>          </execution>        </executions>      </plugin>      <plugin>        <artifactId>maven-jar-plugin</artifactId>        <version>2.4</version>        <executions>          <execution>            <id>default-jar</id>            <phase>package</phase>            <goals>              <goal>jar</goal>            </goals>          </execution>        </executions>      </plugin>      <plugin>        <artifactId>maven-compiler-plugin</artifactId>        <version>3.1</version>        <executions>          <execution>            <id>default-compile</id>            <phase>compile</phase>            <goals>              <goal>compile</goal>            </goals>          </execution>          <execution>            <id>default-testCompile</id>            <phase>test-compile</phase>            <goals>              <goal>testCompile</goal>            </goals>          </execution>        </executions>      </plugin>      <plugin>        <artifactId>maven-surefire-plugin</artifactId>        <version>2.12.4</version>        <executions>          <execution>            <id>default-test</id>            <phase>test</phase>            <goals>              <goal>test</goal>            </goals>          </execution>        </executions>      </plugin>      <plugin>        <artifactId>maven-install-plugin</artifactId>        <version>2.4</version>        <executions>          <execution>            <id>default-install</id>            <phase>install</phase>            <goals>              <goal>install</goal>            </goals>          </execution>        </executions>      </plugin>      <plugin>        <artifactId>maven-deploy-plugin</artifactId>        <version>2.7</version>        <executions>          <execution>            <id>default-deploy</id>            <phase>deploy</phase>            <goals>              <goal>deploy</goal>            </goals>          </execution>        </executions>      </plugin>      <plugin>        <artifactId>maven-site-plugin</artifactId>        <version>3.3</version>        <executions>          <execution>            <id>default-site</id>            <phase>site</phase>            <goals>              <goal>site</goal>            </goals>            <configuration>              <outputDirectory>D:\maven\target\site</outputDirectory>              <reportPlugins>                <reportPlugin>                  <groupId>org.apache.maven.plugins</groupId>                  <artifactId>maven-project-info-reports-plugin</artifactId>                </reportPlugin>              </reportPlugins>            </configuration>          </execution>          <execution>            <id>default-deploy</id>            <phase>site-deploy</phase>            <goals>              <goal>deploy</goal>            </goals>            <configuration>              <outputDirectory>D:\maven\target\site</outputDirectory>              <reportPlugins>                <reportPlugin>                  <groupId>org.apache.maven.plugins</groupId>                  <artifactId>maven-project-info-reports-plugin</artifactId>                </reportPlugin>              </reportPlugins>            </configuration>          </execution>        </executions>        <configuration>          <outputDirectory>D:\maven\target\site</outputDirectory>          <reportPlugins>            <reportPlugin>              <groupId>org.apache.maven.plugins</groupId>              <artifactId>maven-project-info-reports-plugin</artifactId>            </reportPlugin>          </reportPlugins>        </configuration>      </plugin>    </plugins>  </build>  <reporting>    <outputDirectory>D:\maven\target\site</outputDirectory>  </reporting></project>[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time:  2.621 s[INFO] Finished at: 2021-02-26T15:25:27+08:00[INFO] ------------------------------------------------------------------------
    

    你可以看到 effective-pom 中包含了 Maven 在执行任务时需要用到的默认目录结构、输出目录、插件、仓库和报表目录等内容。

    实际开发过程中,Maven 的 pom.xml 文件不需要手工编写,Maven 提供了大量的原型(Archetype)插件来创建项目,包括项目结构和 pom.xml。

2.4 坐标

坐标组成是 groupid, artifiactId, version。 坐标概念来自数学。·

坐标作用:确定资源的,是资源的唯一标识。 在maven中,每个资源都是坐标。 坐标值是唯一的。简称叫gav

节点描述
groupId项目组 ID,定义当前 Maven 项目隶属的组织或公司,通常是唯一的。它的取值一般是项目所属公司或组织的网址或 URL 的反写,例如 net.biancheng.www。
artifactId项目 ID,通常是项目的名称。groupId 和 artifactId 一起定义了项目在仓库中的位置。
version项目版本。
  <groupId>com.bjpowernode</groupId>  <artifactId>ch01-maven</artifactId>  <version>1.0-SNAPSHOT</version>  <packaging>jar</packaging>groupId: 组织名称,代码。 公司,团体或者单位的标识。 这个值常使用的公司域名的倒写。         例如:学校的网站 www.bjpowernode.com, groupId: com.bjpowernode         如果项目规模比较大, 也可以是 域名倒写+大项目名称。	     例如: www.baidu.com ,  无人车: com.baidu.appolloartifactId:项目名称, 如果groupId中有项目, 此时当前的值就是子项目名。 项目名称是唯一的。version:版本, 项目的版本号, 使用的数字。 三位组成。 例如 主版本号.次版本号.小版本号, 例如: 5.2.5。         注意:版本号中有-SNAPSHOT, 表示快照,不是稳定的版本。         packaging 项目打包的类型, 有jar ,war, ear, pom等等 默认是jar

项目使用gav:

1.每个maven项目,都需要有一个自己的gav

2.管理依赖,需要使用其他的jar ,也需要使用gav作为标识。

搜索坐标的地址: https://mvnrepository.com/

2.4 依赖 dependency

依赖:项目中要使用的其他资源(jar)。

需要使用maven表示依赖,管理依赖。 通过使用dependency和gav一起完成依赖的使用

需要在pom.xml文件中,使用dependencies 和dependency, 还有gav 完成依赖的说明。

格式:

<dependencies>      <!-- 日志 -->    <dependency>        <groupId>log4j</groupId>        <artifactId>log4j</artifactId>        <version>1.2.17</version>    </dependency>        <!-- mysql驱动 -->     <dependency>        <groupId>mysql</groupId>        <artifactId>mysql-connector-java</artifactId>        <version>5.1.16</version>    </dependency>        <dependency>        <groupId>javax.servlet</groupId>        <artifactId>servlet-api</artifactId>        <version>2.5</version>        <scope>provided</scope>    </dependency></dependencies> maven使用gav作为标识,从互联网下载依赖的jar。 下载到你的本机上。  由maven管理项目使用的这些jar

dependencies 元素可以包含一个或者多个 dependency 子元素,用以声明一个或者多个项目依赖,每个依赖都可以包含以下元素:

  • groupId、artifactId 和 version:依赖的基本坐标,对于任何一个依赖来说,基本坐标是最重要的,Maven 根据坐标才能找到需要的依赖。
  • type:依赖的类型,对应于项目坐标定义的 packaging。大部分情况下,该元素不必声明,其默认值是 jar。
  • scope:依赖的范围。
  • optional:标记依赖是否可选。
  • exclusions:用来排除传递性依赖。

获取依赖坐标:通常情况下,绝大部分依赖的 Maven 坐标都能在 https://mvnrepository.com/ 中获取。

2.5 仓库

1、仓库是存东西的,Maven 的仓库存放的是:

  1. maven工具自己的jar包。

  2. 第三方的其他jar, 比如项目中要使用mysql驱动。

  3. 自己写的程序,可以打包为jar 。 存放到仓库。

2、Maven 仓库的分类如下图。

image-20211010212517949

3、仓库的分类:

  1. 本地仓库(本机仓库): 位于你自己的计算机, 它是磁盘中的某个目录。

    本地仓库:默认路径,是你登录操作系统的账号的目录中/.m2/repository

         C:\Users\NING MEI\.m2\repository
    

    修改本地仓库的位置:修改maven工具的配置文件(maven的安装路径\conf\setting.xml)

    ​ 步骤:

    ​ 1)创建一个目录,作为仓库使用。 目录不要有中文和空格。 目录不要太深。

    ​ 例如: D:\openrepository

    ​ 2)修改setting.xml文件,指定 D:\openrepository这个目录

        <localRepository>D:/openrepository</localRepository>
    

    ​ 3) 把我给你提供的 仓库的资源 拷贝到 D:/openrepository

  2. 远程仓库: 需要通过联网访问的

    1)中央仓库: 一个ftp服务器, 存放了所有的资源。

    2)中央仓库的镜像: 就是中央仓库的拷贝。 在各大主要城市都有镜像。

    3)私服:在局域网中使用的。 私服就是自己的仓库服务器。 在公司内部使用的。

maven使用仓库: maven自动使用仓库, 当项目启动后, 执行了maven的命令, maven首先访问的是本地仓库, 从仓库中获取所需的jar, 如果本地仓库没有 ,需要访问私服或者中央仓库或者镜像。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sc2WyCuZ-1634806280181)(images/image-20201016114322189.png)]

2.6 Maven的生命周期,插件和命令

1、maven生命周期(clean+site+default):

1)定义:

​ maven的生命周期: 项目构建的各个阶段。 包括 清理, 编译, 测试,报告,打包,安装,部署,不可打乱顺序。

2)三套生命周期
一、说明:
  • Maven 拥有三套标准的生命周期:
    • clean:用于清理项目
    • default:用于构建项目
    • site:用于建立项目站点
二、构建阶段:
  • 每套生命周期包含一系列的构建阶段(phase),这些阶段是有顺序的,且后面的阶段依赖于前面的阶段。用户与 Maven 最直接的交互方式就是调用这些生命周期阶段。以 clean 生命周期为例,它包含 pre-clean、clean 以及 post-clean 三个阶段,当用户调用 pre-clean 阶段时,则只有 pre-clean 阶段执行;当用户调用 clean 阶段时,pre-clean 和 clean 阶段都会执行。当用户调用 post-clean 阶段时,则 pre-clean、clean 以及 post-clean 三个阶段都会执行。

    通过将阶段名传递给 mvn 命令,就可以调用构建阶段,例如:

    mvn install
    
三、生命周期的独立性:
  • 与构建阶段的前后依赖关系不同,三套生命周期本身时相互独立的,用户可以只调用 clean 生命周期的某个阶段,也可以只调用 default 生命周期的某个阶段,而不会对其他生命周期造成任何影响。
四、clean 生命周期:
  • clean 生命周期包括以下 3 个阶段。

    • pre-clean(清理前)
    • clean(清理)
    • post-clean(清理后)
  • 示例

    下面我们将 maven-antrun-plugin 插件的 run 目标绑定到 pre-clean、clean 和 post-clean 三个阶段中,以实现在 clean 生命周期的各个阶段中显示自定义文本信息,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 https://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>net.biancheng.www</groupId>    <artifactId>maven</artifactId>    <version>0.0.1-SNAPSHOT</version>    <dependencies>        <!-- junit依赖 -->        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>            <version>4.9</version>            <scope>compile</scope>        </dependency>        <!-- log4j依赖 -->        <dependency>            <groupId>log4j</groupId>            <artifactId>log4j</artifactId>            <version>1.2.17</version>        </dependency>    </dependencies>    <build>        <plugins>            <!-- 添加插件 maven-antrun-plugin -->            <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-antrun-plugin</artifactId>                <version>1.1</version>                <executions>                    <execution>                        <!--自定义阶段 id -->                        <id>www.biancheng.net pre-clean</id>                        <!--阶段 -->                        <phase>pre-clean</phase>                        <!--目标 -->                        <goals>                            <goal>run</goal>                        </goals>                        <!--配置 -->                        <configuration>                            <!-- 执行的任务 -->                            <tasks>                                <!-- 输出自定义文本信息 -->                                <echo>预清理阶段,编程帮 欢迎您的到来,网址:www.biancheng.net</echo>                            </tasks>                        </configuration>                    </execution>                    <execution>                        <!--自定义阶段 id -->                        <id>www.biancheng.net clean</id>                        <!--阶段 -->                        <phase>clean</phase>                        <!--目标 -->                        <goals>                            <goal>run</goal>                        </goals>                        <!--配置 -->                        <configuration>                            <!-- 执行的任务 -->                            <tasks>                                <!--自定义文本信息 -->                                <echo>清理阶段,编程帮 欢迎您的到来,网址:www.biancheng.net</echo>                            </tasks>                        </configuration>                    </execution>                    <execution>                        <!--自定义阶段 id -->                        <id>www.biancheng.net post-clean</id>                        <!--阶段 -->                        <phase>post-clean</phase>                        <!-- 目标 -->                        <goals>                            <goal>run</goal>                        </goals>                        <!--配置 -->                        <configuration>                            <!-- 执行的任务 -->                            <tasks>                                <!-- 执行的任务 -->                                <echo>后清理阶段,编程帮 欢迎您的到来,网址:www.biancheng.net</echo>                            </tasks>                        </configuration>                    </execution>                </executions>            </plugin>        </plugins>    </build></project>打开命令行窗口,跳转到 pom.xml 所在的目录,执行命令mvn post-clean,结果如下。[INFO] Scanning for projects...[INFO][INFO] ----------------------< net.biancheng.www:maven >-----------------------[INFO] Building maven 0.0.1-SNAPSHOT[INFO] --------------------------------[ jar ]---------------------------------[INFO][INFO] --- maven-antrun-plugin:1.1:run (www.biancheng.net pre-clean) @ maven ---[INFO] Executing tasks     [echo] 预清理阶段,编程帮 欢迎您的到来,网址:www.biancheng.net[INFO] Executed tasks[INFO][INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ maven ---[INFO][INFO] --- maven-antrun-plugin:1.1:run (www.biancheng.net clean) @ maven ---[INFO] Executing tasks     [echo] 清理阶段,编程帮 欢迎您的到来,网址:www.biancheng.net[INFO] Executed tasks[INFO][INFO] --- maven-antrun-plugin:1.1:run (www.biancheng.net post-clean) @ maven ---[INFO] Executing tasks     [echo] 后清理阶段,编程帮 欢迎您的到来,网址:www.biancheng.net[INFO] Executed tasks[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time:  0.365 s[INFO] Finished at: 2021-03-01T13:25:07+08:00[INFO] ------------------------------------------------------------------------
    
五、default 生命周期:
  • default 生命周期各个阶段

    default 定义了项目真正构建时所需要的所有步骤,它是所有生命周期中最核心,最重要的部分,default 生命周期包含非常多的阶段,如下表。

    阶段描述
    validate验证项目是否正确以及所有必要信息是否可用。
    initialize初始化构建状态。
    generate-sources生成编译阶段需要的所有源码文件。
    process-sources处理源码文件,例如过滤某些值。
    generate-resources生成项目打包阶段需要的资源文件。
    process-resources处理资源文件,并复制到输出目录,为打包阶段做准备。
    compile编译源代码,并移动到输出目录。
    process-classes处理编译生成的字节码文件
    generate-test-sources生成编译阶段需要的测试源代码。
    process-test-sources处理测试资源,并复制到测试输出目录。
    test-compile编译测试源代码并移动到测试输出目录中。
    test使用适当的单元测试框架(例如 JUnit)运行测试。
    prepare-package在真正打包之前,执行一些必要的操作。
    package获取编译后的代码,并按照可发布的格式进行打包,例如 JAR、WAR 或者 EAR 文件。
    pre-integration-test在集成测试执行之前,执行所需的操作,例如设置环境变量。
    integration-test处理和部署所需的包到集成测试能够运行的环境中。
    post-integration-test在集成测试被执行后执行必要的操作,例如清理环境。
    verify对集成测试的结果进行检查,以保证质量达标。
    install安装打包的项目到本地仓库,以供其他项目使用。
    deploy拷贝最终的包文件到远程仓库中,以共享给其他开发人员和项目。
  • 示例:

    将 maven-antrun-plugin 插件的 run 目标绑定 default 生命周期的部分阶段中,以实现在 default 生命周期的特定阶段中显示定义文本信息。

    更新 D:\maven 文件夹中的 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>net.biancheng.www</groupId>    <artifactId>maven</artifactId>    <version>0.0.1-SNAPSHOT</version>    <dependencies>        <!-- junit依赖 -->        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>            <version>4.9</version>            <scope>compile</scope>        </dependency>        <!-- log4j依赖 -->        <dependency>            <groupId>log4j</groupId>            <artifactId>log4j</artifactId>            <version>1.2.17</version>        </dependency>    </dependencies>    <build>        <plugins>            <!-- 添加插件 maven-antrun-plugin -->            <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-antrun-plugin</artifactId>                <version>1.1</version>                <executions>                    <execution>                        <id>www.biancheng.net validate</id>                        <phase>validate</phase>                        <goals>                            <goal>run</goal>                        </goals>                        <configuration>                            <tasks>                                <echo>编程帮 欢迎您的到来,网址:www.biancheng.net 验证阶段……</echo>                            </tasks>                        </configuration>                    </execution>                    <execution>                        <id>www.biancheng.net compile</id>                        <phase>compile</phase>                        <goals>                            <goal>run</goal>                        </goals>                        <configuration>                            <tasks>                                <echo>编程帮 欢迎您的到来,网址:www.biancheng.net 编译阶段……</echo>                            </tasks>                        </configuration>                    </execution>                    <execution>                        <id>www.biancheng.net test</id>                        <phase>test</phase>                        <goals>                            <goal>run</goal>                        </goals>                        <configuration>                            <tasks>                                <echo>编程帮 欢迎您的到来,网址:www.biancheng.net 测试阶段……</echo>                            </tasks>                        </configuration>                    </execution>                    <execution>                        <id>www.biancheng.net package</id>                        <phase>package</phase>                        <goals>                            <goal>run</goal>                        </goals>                        <configuration>                            <tasks>                                <echo>编程帮 欢迎您的到来,网址:www.biancheng.net 打包阶段……</echo>                            </tasks>                        </configuration>                    </execution>                    <execution>                        <id>www.biancheng.net deploy</id>                        <phase>deploy</phase>                        <goals>                            <goal>run</goal>                        </goals>                        <configuration>                            <tasks>                                <echo>编程帮 欢迎您的到来,网址:www.biancheng.net 部署阶段……</echo>                            </tasks>                        </configuration>                    </execution>                </executions>            </plugin>        </plugins>    </build></project>
    

    打开命令行窗口,跳转到 pom.xml 所在的目录,执行命令:D:\maven>mvn compile,结果如下。

    [INFO] Scanning for projects...[INFO][INFO] ----------------------< net.biancheng.www:maven >-----------------------[INFO] Building maven 0.0.1-SNAPSHOT[INFO] --------------------------------[ jar ]---------------------------------[INFO][INFO] --- maven-antrun-plugin:1.1:run (www.biancheng.net validate) @ maven ---[INFO] Executing tasks     [echo] 编程帮 欢迎您的到来,网址:www.biancheng.net 验证阶段……[INFO] Executed tasks[INFO][INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ maven ---[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent![INFO] skip non existing resourceDirectory D:\maven\src\main\resources[INFO][INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ maven ---[INFO] No sources to compile[INFO][INFO] --- maven-antrun-plugin:1.1:run (www.biancheng.net compile) @ maven ---[INFO] Executing tasks     [echo] 编程帮 欢迎您的到来,网址:www.biancheng.net 编译阶段……[INFO] Executed tasks[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time:  0.652 s[INFO] Finished at: 2021-03-01T15:07:50+08:00[INFO] ------------------------------------------------------------------------
    
六、site 生命周期:
  • 说明:

    sit 生命周期的目的是建立和部署项目站点,Maven 能够根据 POM 包含的信息,自动生成一个友好的站点,该站点包含一些与该项目相关的文档。

  • site 生命周期包含以下 4 个阶段:

    • pre-site
    • site
    • post-site
    • site-deploy
  • 示例:

    下面我们将 maven-antrun-plugin 插件的 run 目标绑定到 site 生命周期的所有阶段中,以实现在该生命周期各个阶段显示自定义文本信息。

    更新 D:\maven 目录下的 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>net.biancheng.www</groupId>    <artifactId>maven</artifactId>    <version>0.0.1-SNAPSHOT</version>    <dependencies>        <!-- junit依赖 -->        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>            <version>4.9</version>            <scope>compile</scope>        </dependency>        <!-- log4j依赖 -->        <dependency>            <groupId>log4j</groupId>            <artifactId>log4j</artifactId>            <version>1.2.17</version>        </dependency>    </dependencies>    <build>        <plugins>            <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-site-plugin</artifactId>                <version>3.7.1</version>            </plugin>            <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-project-info-reports-plugin</artifactId>                <version>3.0.0</version>            </plugin>            <!-- 添加插件 maven-antrun-plugin -->            <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-antrun-plugin</artifactId>                <version>1.3</version>                <executions>                    <execution>                        <id>www.bianchengbang.net pre-site</id>                        <phase>pre-site</phase>                        <goals>                            <goal>run</goal>                        </goals>                        <configuration>                            <tasks>                                <echo>编程帮 欢迎您的到来,网址:www.biancheng.net pre-site 阶段……</echo>                            </tasks>                        </configuration>                    </execution>                    <execution>                        <id>www.bianchengbang.net site</id>                        <phase>site</phase>                        <goals>                            <goal>run</goal>                        </goals>                        <configuration>                            <tasks>                                <echo>编程帮 欢迎您的到来,网址:www.biancheng.net site 阶段……</echo>                            </tasks>                        </configuration>                    </execution>                    <execution>                        <id>www.bianchengbang.net post-site</id>                        <phase>post-site</phase>                        <goals>                            <goal>run</goal>                        </goals>                        <configuration>                            <tasks>                                <echo>编程帮 欢迎您的到来,网址:www.biancheng.net post-site 阶段……</echo>                            </tasks>                        </configuration>                    </execution>                    <execution>                        <id>www.bianchengbang.net site-deploy</id>                        <phase>site-deploy</phase>                        <goals>                            <goal>run</goal>                        </goals>                        <configuration>                            <tasks>                                <echo>编程帮 欢迎您的到来,网址:www.biancheng.net site-deploy 阶段……</echo>                            </tasks>                        </configuration>                    </execution>                </executions>            </plugin>        </plugins>    </build></project>
    

    打开命令行窗口,跳转到 pom.xml 所在的目录,执行 mvn 命令:mvn post-site,结果如下。

    [INFO] Scanning for projects...[INFO][INFO] ----------------------< net.biancheng.www:maven >-----------------------[INFO] Building maven 0.0.1-SNAPSHOT[INFO] --------------------------------[ jar ]---------------------------------[INFO][INFO] --- maven-antrun-plugin:1.3:run (www.bianchengbang.net pre-site) @ maven ---[INFO] Executing tasks     [echo] 编程帮 欢迎您的到来,网址:www.biancheng.net pre-site 阶段……[INFO] Executed tasks[INFO][INFO] --- maven-site-plugin:3.7.1:site (default-site) @ maven ---[WARNING] Input file encoding has not been set, using platform encoding GBK, i.e. build is platform dependent![INFO] configuring report plugin org.apache.maven.plugins:maven-project-info-reports-plugin:3.0.0[INFO] 15 reports detected for maven-project-info-reports-plugin:3.0.0: ci-management, dependencies, dependency-info, dependency-management, distribution-management, index, issue-management, licenses, mailing-lists, modules, plugin-management, plugins, scm, summary, team[INFO] Rendering site with default locale English (en)[WARNING] No project URL defined - decoration links will not be relativized![INFO] Rendering content with org.apache.maven.skins:maven-default-skin:jar:1.2 skin.[INFO] Generating "Dependencies" report  --- maven-project-info-reports-plugin:3.0.0:dependencies[INFO] Generating "Dependency Information" report --- maven-project-info-reports-plugin:3.0.0:dependency-info[INFO] Generating "About" report         --- maven-project-info-reports-plugin:3.0.0:index[INFO] Generating "Plugin Management" report --- maven-project-info-reports-plugin:3.0.0:plugin-management[INFO] Generating "Plugins" report       --- maven-project-info-reports-plugin:3.0.0:plugins[INFO] Generating "Summary" report       --- maven-project-info-reports-plugin:3.0.0:summary[INFO][INFO] --- maven-antrun-plugin:1.3:run (www.bianchengbang.net site) @ maven ---[INFO] Executing tasks     [echo] 编程帮 欢迎您的到来,网址:www.biancheng.net site 阶段……[INFO] Executed tasks[INFO][INFO] --- maven-antrun-plugin:1.3:run (www.bianchengbang.net post-site) @ maven ---[INFO] Executing tasks     [echo] 编程帮 欢迎您的到来,网址:www.biancheng.net post-site 阶段……[INFO] Executed tasks[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time:  2.824 s[INFO] Finished at: 2021-03-01T16:02:44+08:00[INFO] ------------------------------------------------------------------------
    

2、插件(plugin):

1)定义:

​ 要完成构建项目的各个阶段,要使用maven的命令, 执行命令的功能是通过插件完成的。插件就是jar,一些类。

​ maven 实际上是一个依赖插件执行的框架,它执行的每个任务实际上都由插件完成的。Maven 的核心发布包中并不包含任何 Maven 插件,它们以独立构件的形式存在, 只有在 Maven 需要使用某个插件时,才会去仓库中下载。

2)插件类型:
  • 插件类型描述
    Build plugins在项目构建过程中执行,在 pom.xml 中的 build 元素中配置
    Reporting plugins在网站生成过程中执行,在 pom.xml 中的 reporting 元素中配置
3)自定义插件:
  • 对于 Maven 插件而言,为了提高代码的复用性,通常一个 Maven 插件能够实现多个功能,每一个功能都是一个插件目标,即 Maven 插件是插件目标的集合。我们可以把插件理解为一个类,而插件目标是类中的方法,调用插件目标就能实现对应的功能。

    通用写法:

    插件目标的通用写法如下。

    [插件名]:[插件目标名]
    

    例如,maven-compiler-plugin 插件的 compile 目标的通用写法如下。

    maven-compiler-plugin:compile
    
  • 执行插件目标:

    使用 Maven 命令执行插件的目标,语法如下。

    mvn [插件名]:[目标名]
    

    例如,调用 maven-compiler-plugin 插件的 compile 目标,命令如下。

    mvn compiler:compile
    
4)插件绑定:
  • 为了完成某个具体的构建任务,Maven 生命周期的阶段需要和 Maven 插件的目标相互绑定。例如,代码编译任务对应了default 生命周期的 compile 阶段,而 maven-compiler-plugin 插件的 compile 目标能够完成这个任务,因此将它们进行绑定就能达到代码编译的目的。

  • 内置绑定

    Maven 默认为一些核心的生命周期阶段绑定了插件目标,当用户调用这些阶段时,对应的插件目标就会自动执行相应的任务。

    生命周期阶段插件目标执行的任务
    cleanpre-clean
    cleanmaven-clean-plugin:clean清理 Maven 的输出目录
    post-clean
    sitepre-site
    sitemaven-site-plugin:site生成项目站点
    post-site
    site-deploymaven-site-plugin:deploy部署项目站点
    defaultprocess-resourcesmaven-resources-plugin:resources复制资源文件到输出目录
    compilemaven-compiler-plugin:compile编译代码到输出目录
    process-test-resourcesmaven-resources-plugin:testResources复制测试资源文件到测试输出目录
    test-compilemaven-compiler-plugin:testCompile编译测试代码到测试输出目录
    testmaven-surefire-plugin:test执行测试用例
    packagemaven-jar-plugin:jar/maven-jar-plugin:war创建项目 jar/war 包
    installmaven-install-plugin:install将项目输出的包文件安装到本地仓库
    deploymaven-deploy-plugin:deploy将项目输出的包文件部署到到远程仓库****

    上表中,default 生命周期中只列出了绑定了插件目标的阶段,它还有很多其他的阶段,但这些阶段默认没有绑定任何插件目标,因此它们也没有任何实际的行为。

    我们可以直接在执行 Maven 命令看到该构建过程包含了哪些插件目标。例如,在 Maven 项目中执行 mvn clean install 命令,能看到如下输出,图中标记的部分就是执行此命令时所调用的插件目标。

    image-20211010223540636
  • 自定义绑定

    除了内置绑定之外,用户也可以自己选择将某个插件目标绑定到 Maven 生命周期的某个阶段上,这种绑定方式就是自定义绑定。自定义绑定能够让 Maven 在构建过程中执行更多更丰富的任务。

    例如,我们想要在 clean 生命周期的 clean 阶段中显示自定义文本信息,则只需要在项目的 POM 中 ,通过 build 元素的子元素 plugins,将 maven-antrun-plugin:run 目标绑定到 clean 阶段上,并使用该插件输出自定义文本信息即可。

    <project>...    <build>        <plugins>            <!-- 绑定插件 maven-antrun-plugin -->            <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-antrun-plugin</artifactId>                <version>1.8</version>                <executions>                    <execution>                        <!--自定义 id -->                        <id>www.biancheng.net clean</id>                        <!--插件目标绑定的构建阶段 -->                        <phase>clean</phase>                        <!--插件目标 -->                        <goals>                            <goal>run</goal>                        </goals>                        <!--配置 -->                        <configuration>                            <!-- 执行的任务 -->                            <tasks>                                <!--自定义文本信息 -->                                <echo>清理阶段,编程帮 欢迎您的到来,网址:www.biancheng.net</echo>                            </tasks>                        </configuration>                    </execution>                               </executions>            </plugin>        </plugins>    </build>...</project>
    

    以上配置中除了插件的坐标信息之外,还通过 executions 元素定义了一些执行配置。executions 下的每一个 executin 子元素都可以用来配置执行一个任务。

    execution 下各个元素含义如下:

    • id:任务的唯一标识。
    • phase:插件目标需要绑定的生命周期阶段。
    • goals:用于指定一组插件目标,其子元素 goal 用于指定一个插件目标。
    • configuration:该任务的配置,其子元素 tasks 用于指定该插件目标执行的任务。

    执行命令 mvn clean ,结果如下。

[INFO] Scanning for projects…[INFO][INFO] ------------------< net.biancheng.www:helloIdeaMaven >------------------[INFO] Building helloIdeaMaven 2.6-SNAPSHOT[INFO] --------------------------------[ jar ]---------------------------------[INFO][INFO] — maven-clean-plugin:3.1.0:clean (default-clean) @ helloIdeaMaven —[INFO] Deleting D:\eclipse workSpace 3\helloIdeaMaven\target[INFO][INFO] — maven-antrun-plugin:1.8:run (www.biancheng.net clean) @ helloIdeaMaven —[WARNING] Parameter tasks is deprecated, use target instead[INFO] Executing tasksmain: [echo] 清理阶段,编程帮 欢迎您的到来,网址:www.biancheng.net[INFO] Executed tasks[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time: 0.753 s[INFO] Finished at: 2021-04-08T10:22:49+08:00[INFO] ------------------------------------------------------------------------


当插件目标绑定到生命周期的不同阶段时,其执行顺序由生命周期阶段的先后顺序决定。如果多个目标绑定到同一个生命周期阶段,其执行顺序与插件声明顺序一致,先声明的先执行,后声明的后执行。


#### 	5)自定义插件:

- 在pom.xml文件中, build标签中。设置插件

org.apache.maven.plugins maven-compiler-plugin 3.8.1 1.8 1.8

### 3、生命周期与插件的关系

Maven 生命周期是抽象的,其本身不能做任何实际工作,这些实际工作(如源代码编译)都通过调用 [Maven 插件](http://c.biancheng.net/maven2/plugin.html) 中的插件目标(plugin goal)完成的。

为了更好的理解 Maven 生命周期、插件以及插件目标三者的关系,我们可以将 Maven 生命周期理解成一个抽象父类,将插件理解成其子类,将插件目标理解成子类中重写的方法,其基本结构与下面的示例代码相似。

package net.biancheng.www;/*** 模拟 maven 生命周期*/public abstract class LifeCycle { //定义构建过程 public void build() { //模拟生命周期各个阶段,即调用插件中目标 clean(); initialize(); compile(); packager(); install(); } //定义清理的过程 public abstract void clean(); //定义初始化的过程 public abstract void initialize(); //定义编译的过程 public abstract void compile(); //定义打包的过程 public abstract void packager(); //定义安装的过程 public abstract void install();}


模拟 clean 插件的子类,代码如下。

package net.biancheng.www;/*** 子类模拟clean 相关的插件*/public abstract class CleanPlugin extends LifeCycle { //重写父类(生命周期)的清理工作 //模拟插件目标 @Override public void clean() { System.out.println(“清理”); }}


​	以上示例中,父类 LifeCycle 模拟的是 Maven 生命周期,子类 CleanPlugin 模拟的是 Maven 插件,而子类中重写的 clean() 模拟的是插件目标。

​	虽然示例中的代码与 Maven 实际代码相去甚远,但它们的基本理念是方法相同的。生命周期抽象了构建的各个步骤,定义了它们的执行顺序,但却没有提供具体的实现。插件中完成了对构建过程的实现,想要完成某个构建步骤,调用插件中的一个或多个插件目标即可。

​	Maven的核心程序中定义了抽象的生命周期,生命周期中各个阶段的具体任务是由插件来完成,

​	生命周期中的每个构建过程都可以绑定一个或多个插件目标,且 Maven 为大多数的构建步骤都绑定了默认的插件。例如,针对源代码编译的插件是 maven-compiler-plugin、针对集成测试的插件是 maven-surefire-plugin 等。

### 4、命令:

####  1、定义:

​		执行maven功能是 由命令发出的。 比如 mvn compile

#### 2、常用命令:

##### 1) mvn clean: 

​		作用:清理命令, 作用删除以前生成的数据, 删除target目录。

​		插件: maven-clean-plugin   , 版本是 2.5

##### 2)mvn compile:

​		作用:编译命令,执行的代码编译, 把src/main/java目录中的java代码编译为class文件。

​		同时把class文件拷贝到 target/classes目录。 这个目录classes是存放类文件的根目录(也叫做类路径,classpath)



​		插件: maven-compiler-plugin 版本3.1。  编译代码的插件maven-resources-plugin 版本2.6 。 资源插件, 处理文件的。 作用是把src/main/resources目录中的文件拷贝target/classes目录中。

##### 3)mvn test-compile: 

​		作用:编译命令, 编译src/test/java目录中的源文件, 把生成的class拷贝到target/test-classes目录。同时把src/test/resources目录中的文件拷贝到 test-clasess目录

​		插件: maven-compiler-plugin 版本3.1。  编译代码的插件

​                maven-resources-plugin 版本2.6 。 资源插件, 处理文件的



##### 4)mvn test:

​		作用:测试命令, 作用执行 test-classes目录的程序, 测试src/main/java目录中的主程序代码是否符合要求。

​		插件: maven-surefire-plugin 版本 2.12.4



##### 5)mvn package:

​		作用:打包,作用是把项目中的资源class文件和配置文件都放到一个压缩文件中, 默认压缩文件是jar类型的。 web应用是war类型, 扩展是jar,war的。

​		插件:maven-jar-plugin 版本 2.4。 执行打包处理。 生成一个jar扩展的文件, 放在target目录下.

​               打包的文件包含的是 src/main目录中的所有的生成的class和配置文件和test无关。



​    生成的是 ch01-maven-1.0-SNAPSHOT.jar

```xml
  <groupId>com.bjpowernode</groupId>  <artifactId>ch01-maven</artifactId>  <version>1.0-SNAPSHOT</version>  <packaging>jar</packaging>打包的文件名: artifactId-version.packaging
6)mvn install :

​ 作用:把生成的打包的文件 ,安装到maven仓库。

​ 插件: maven-install-plugin 版本 2.4 。 把生成的jar文件安装到本地仓库。

​ 查看查看中的jar文件:

  <groupId>com.bjpowernode</groupId>  <artifactId>ch01-maven</artifactId>  <version>1.0-SNAPSHOT</version>  <packaging>jar</packaging>groupId中的值, 如果有 "." 前和后都是独立的文件夹。 com\bjpowernodeartifactId, 独立的文件夹version,独立的文件夹

2.7 Maven 导入本地jar包

1、说明:

​ 我们知道,Maven 是通过仓库对依赖进行管理的,当 Maven 项目需要某个依赖时,只要其 POM 中声明了依赖的坐标信息,Maven 就会自动从仓库中去下载该构件使用。但在实际的开发过程中,经常会遇到一种情况:某一个项目需要依赖于存储在本地的某个 jar 包,该 jar 包无法从任何仓库中下载的,这种依赖被称为外部依赖或本地依赖。那么这种依赖是如何声明的呢?

2、示例:

下面我们通过一个实例实例来介绍如何导入本地 jar 包。

  1. 打开命令行窗口,跳转到 D:\maven 目录下,执行以下 mvn 命令,创建一个名为 secondMaven 的项目。
mvn archetype:generate -DgroupId=net.biancheng.www -DartifactId=secondMaven -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
  1. 更新 secondMaven 中 App 类的代码如下。
package net.biancheng.www;import net.biancheng.www.Util;;public class App {    public static void main(String[] args) {        Util.printMessage("secondMaven");    }}

由以上代码可以看出,secondMaven 中的 App 类需要使用 helloMaven 中独有的 Util 类,即 secondMaven 需要依赖于 helloMaven。

  1. 跳转到 helloMaven 所在的目录,执行以下 mvn 命令, 将该项目打包成 jar 文件。
mvn clean package
  1. 命令执行完成后,进入 D:\maven\helloMaven\target 目录,可以看到 Maven 已经将 helloMaven 项目打包成 helloMaven-1.0-SNAPSHOT.jar。

    image-20211010232145855
  2. 修改 secondMaven 中 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/maven-v4_0_0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>net.biancheng.www</groupId>    <artifactId>secondMaven</artifactId>    <packaging>jar</packaging>    <version>1.0-SNAPSHOT</version>    <name>secondMaven</name>    <url>http://maven.apache.org</url>    <dependencies>        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>            <version>3.8.1</version>            <scope>test</scope>        </dependency>        <!--外部依赖-->        <dependency>            <groupId>net.biancheng.www</groupId>            <artifactId>helloMaven</artifactId>             <!--依赖范围-->            <scope>system</scope>            <version>1.0-SNAPSHOT</version>            <!--依赖所在位置-->            <systemPath>D:\maven\helloMaven\target\helloMaven-1.0-SNAPSHOT.jar</systemPath>        </dependency>    </dependencies></project>
    

    在以上配置中,除了依赖的坐标信息外,外部依赖还使用了 scope 和 systemPath 两个元素。

    • scope 表示依赖范围,这里取值必须是 system,即系统。
    • systemPath 表示依赖的本地构件的位置。
  3. 打开命令行窗口,跳转到 secondMaven 所在目录,执行以下 mvn 命令,进行编译。

    mvn clean compile
    

    命令执行结果如下。

    [WARNING][WARNING] Some problems were encountered while building the effective model for net.biancheng.www:secondMaven:jar:1.0-SNAPSHOT[WARNING] 'dependencies.dependency.systemPath' for net.biancheng.www:helloMaven:jar should use a variable instead of a hard-coded path D:\maven\helloMaven\target\helloMaven-1.0-SNAPSHOT.jar @ line 23, column 16[WARNING][WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.[WARNING][WARNING] For this reason, future Maven versions might no longer support building such malformed projects.[WARNING][INFO][INFO] -------------------< net.biancheng.www:secondMaven >--------------------[INFO] Building secondMaven 1.0-SNAPSHOT[INFO] --------------------------------[ jar ]---------------------------------[INFO][INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ secondMaven ---[INFO] Deleting d:\maven\secondMaven\target[INFO][INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ secondMaven ---[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent![INFO] skip non existing resourceDirectory d:\maven\secondMaven\src\main\resources[INFO][INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ secondMaven ---[INFO] Changes detected - recompiling the module![WARNING] File encoding has not been set, using platform encoding GBK, i.e. build is platform dependent![INFO] Compiling 1 source file to d:\maven\secondMaven\target\classes[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time:  1.030 s[INFO] Finished at: 2021-03-03T14:05:00+08:00[INFO] ------------------------------------------------------------------------
    
  4. 编译完成后,执行以下命令,设置临时环境变量。

    set classpath=%classpath%;D:\maven\helloMaven\target\helloMaven-1.0-SNAPSHOT.jar
    
  5. 执行以下 Java 命令。

    java net.biancheng.www.App
    
  6. 结果如下图。

    image-20211010232341174

2.8 Maven SNAPSHOT(快照)

1、说明:

我们知道,Maven 项目第一构建时,会自动从远程仓库搜索依赖项,并将其下载到本地仓库中。当项目再进行构建时,会直接从本地仓库搜索依赖项并引用,而不会再次向远程仓库获取。这样的设计能够避免项目每次构建时都去远程仓库下载依赖,减轻了网络带宽的压力,但也带来了问题。

大型的应用软件通常由多个功能模块组成,这些模块一般分别于不同的团队负责开发。假设有两个团队,他们分别负责项目中的 app-ui(前端) 和 data-service(数据服务) 两个模块,且 app-ui 需要依赖 data-service 项目作为数据服务来源。

基于以上假设,若 data-service 团队正在进行快节奏的 bug 修复及功能增强,会在短时间内高频率地更新代码以及发布版本。就会出现以下情况:

  1. data-service 团队每次发布新版本更新代码时,都应该通知 app-ui 团队。
  2. app-ui 团队则需要定期更新其 pom.xml 以获得最新的版本。

这样,势必会影响开发效率,甚至会影响项目的验收及投产。要解决这个问题,其实很简单,那就是使用 SNAPSHOT(快照)版本。

2、SNAPSHOT 是什么:

SNAPSHOT(快照)是一种特殊的版本,它表示当前开发进度的副本。与常规版本不同,快照版本的构件在发布时,Maven 会自动为它打上一个时间戳,有了这个时间戳后,当依赖该构件的项目进行构建时,Maven 就能从仓库中找到最新的 SNAPSHOT 版本文件

​ 定义一个组件或模块为快照版本,只需要在其 pom.xml 中版本号(version 元素的值)后加上 -SNAPSHOT 即可,例如:

<groupId>net.biancheng.www</groupId><artifactId>helloMaven</artifactId><packaging>jar</packaging><version>1.0-SNAPSHOT</version>

要解决上面的问题,现在就十分简单了:data-servcie 团队每次更新代码都使用快照版本发布到仓库中,app-ui 团队则引用快照版本的依赖,这样 app-ui 不再需要重复修改 pom.xml 中的配置,每次构建时都会自动从仓库中获取最新的构件。

默认情况下对于快照本本的构件,Maven 会每天从仓库中获取一次更新,用户也可以在任何 Maven 命令中使用 -U 参数强制 Maven 检查更新。命令如下:

mvn clean package -U

3、SNAPSHOT 版本 VS RELEASE 版本:

​ Maven 仓库分为两种,Snapshot 快照仓库和 Release 发行仓库。Snapshot 快照仓库用于保存开发过程中的不稳定 SNAPSHOT 版本,Release 发行仓库则用来保存稳定的 RELEASE 版本。

​ Maven 会根据模块的版本号(pom.xml 文件中的 version 元素)中是否带有 -SNAPSHOT 来判断是 SNAPSHOT 版本还是正式 RELEASE 版本。带有 -SNAPSHOT 是SNAPSHOT(快照)版本,不带 -SNAPSHOT 的就是正式 RELEASE(发布)版本。

SNAPSHOT 版本和 RELEASE 版本区别如下表。

区别SNAPSHOT 版本RELEASE 版本
定义版本号中带有 -SNAPSHOT版本号中不带有 -SNAPSHOT
发布仓库Snapshot 快照仓库Release 发行仓库
是否从远程仓库自动获取更新在不更改版本号的前提下,直接编译打包时,Maven 会自动从远程仓库上下载最新的快照版本。在不更改版本号的前提下,直接编译打包时,如果本地仓库已经存在该版本的模块,则 Maven 不会主动去远程仓库下载。
稳定性快照版本往往对应了大量带有时间戳的构件,具有不稳定性。发布版本只对应了唯一的构件,具有稳定性。
使用场景快照版本只应该在组织内部的项目中依赖使用。Maven 项目使用的组织外的依赖项都应该时发布版本的,不应该使用任何的快照版本依赖,否则会造成潜在的风险。
发布前是否需要修改当项目经过完善的测试后,需要上线时,应该将项目从快照版本更改为发布版本不需要修改

4、示例:

打开命令行窗口,跳转到 D:\maven\secondMaven 目录,执行以下 mvn 命令。

mvn clean package -U

命令执行结果如下。

[INFO] Scanning for projects...[WARNING][WARNING] Some problems were encountered while building the effective model for net.biancheng.www:secondMaven:jar:1.0-SNAPSHOT[WARNING] 'dependencies.dependency.systemPath' for net.biancheng.www:helloMaven:jar should use a variable instead of a hard-coded path D:\maven\helloMaven\target\helloMaven-1.0-SNAPSHOT.jar @ line 37, column 16[WARNING][WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.[WARNING][WARNING] For this reason, future Maven versions might no longer support building such malformed projects.[WARNING][INFO][INFO] -------------------< net.biancheng.www:secondMaven >--------------------[INFO] Building secondMaven 1.0-SNAPSHOT[INFO] --------------------------------[ jar ]---------------------------------[INFO][INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ secondMaven ---[INFO] Deleting D:\maven\secondMaven\target[INFO][INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ secondMaven ---[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent![INFO] skip non existing resourceDirectory D:\maven\secondMaven\src\main\resources[INFO][INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ secondMaven ---[INFO] Changes detected - recompiling the module![WARNING] File encoding has not been set, using platform encoding GBK, i.e. build is platform dependent![INFO] Compiling 1 source file to D:\maven\secondMaven\target\classes[INFO][INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ secondMaven ---[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent![INFO] skip non existing resourceDirectory D:\maven\secondMaven\src\test\resources[INFO][INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ secondMaven ---[INFO] Changes detected - recompiling the module![WARNING] File encoding has not been set, using platform encoding GBK, i.e. build is platform dependent![INFO] Compiling 1 source file to D:\maven\secondMaven\target\test-classes[INFO][INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ secondMaven ---[INFO] Surefire report directory: D:\maven\secondMaven\target\surefire-reports-------------------------------------------------------T E S T S-------------------------------------------------------Running net.biancheng.www.AppTestTests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.008 secResults :Tests run: 1, Failures: 0, Errors: 0, Skipped: 0[INFO][INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ secondMaven ---[INFO] Building jar: D:\maven\secondMaven\target\secondMaven-1.0-SNAPSHOT.jar[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time:  2.413 s[INFO] Finished at: 2021-03-04T10:24:32+08:00[INFO] ------------------------------------------------------------------------

2.9 Maven 自动化构建

1、说明:

Maven 自动化构建是一种方案,即当某个项目构建完成后(特别是有代码更新的情况下),所有依赖它的相关项目也应该开始构建过程,以确保这些项目的稳定运行。

Maven 的自动化构建主要通过如下两种方案实现:

  • 使用 maven-invoker-plugin 插件。
  • 使用持续集成(CI)服务器自动管理构建自动化,例如 Jenkins (了解即可)。

2、示例:

使用 maven-invoker-plugin 插件

Maven 社区提供了一个名为 maven-invoker-plugin 的插件,该插件能够用来在一组项目上执行构建工作,并检查每个项目是否构建成功,通过它就可以实现 Maven 的自动化构建。

如下图所示,在 D:\maven 目录下有 3 个 Maven 项目。

image-20211011083740760

其中,helloMaven 项目的 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/maven-v4_0_0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>net.biancheng.www</groupId>    <artifactId>helloMaven</artifactId>    <packaging>jar</packaging>    <version>1.0-SNAPSHOT</version>    <name>helloMaven</name>    <url>http://maven.apache.org</url>    <dependencies>        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>            <version>3.8.1</version>            <scope>test</scope>        </dependency>    </dependencies>    <build>        <plugins>            <!-- 添加invoker 插件 -->            <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-invoker-plugin</artifactId>                <version>3.2.2</version>                <configuration>                    <debug>true</debug>                    <!--设置 invkoer插件 添加的 pom 文件所在的文件夹  -->                    <projectsDirectory>D:\maven</projectsDirectory>                    <!-- 设置 invkoer插件 添加的 pom 文件 -->                    <pomIncludes>                        <pomInclude>secondMaven\pom.xml</pomInclude>                        <pomInclude>thirdMaven\pom.xml</pomInclude>                    </pomIncludes>                </configuration>                <executions>                    <execution>                        <id>id-integration-test</id>                        <!-- 执行的目标 -->                        <goals>                            <goal>run</goal>                        </goals>                    </execution>                </executions>            </plugin>        </plugins>    </build></project>

以上配置中,在 build 的 plugins 子元素中使用了一个 plugin 元素声明了一个构建期的插件 maven-invoker-plugin,该插件配置中各元素含义如下:

  • groupId:插件的项目组 id;
  • artifactId:插件的项目或模块 id;
  • version:插件的版本;
  • projectsDirectory:需要构建项目的目录,该元素可单独使用,表示该目录下的所有 Maven 项目都会在当前项目构建完成后开始构建;
  • pomIncludes:该元素内可以声明一个或多个 pomInclude 元素,需与 projectDirectory 元素配合使用,共同指定需要构建项目的 pom.xml。

secondMaven 项目依赖于 helloMaven ,其 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/maven-v4_0_0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>net.biancheng.www</groupId>    <artifactId>secondMaven</artifactId>    <packaging>jar</packaging>    <version>1.0-SNAPSHOT</version>    <name>secondMaven</name>    <url>http://maven.apache.org</url>    <build>        <plugins>            <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-site-plugin</artifactId>                <version>3.7.1</version>            </plugin>            <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-project-info-reports-plugin</artifactId>                <version>3.0.0</version>            </plugin>        </plugins>    </build>    <dependencies>        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>            <version>3.8.1</version>            <scope>test</scope>        </dependency>        <dependency>            <groupId>net.biancheng.www</groupId>            <artifactId>helloMaven</artifactId>            <scope>system</scope>            <version>1.0-SNAPSHOT</version>            <systemPath>D:\maven\helloMaven\target\helloMaven-1.0-SNAPSHOT.jar</systemPath>        </dependency>    </dependencies></project>

thirdMaven 项目依赖于 helloMaven ,其 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>net.biancheng.www</groupId>    <artifactId>thirdMaven</artifactId>    <version>1.0-SNAPSHOT</version>    <name>thirdMaven</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>            <groupId>junit</groupId>            <artifactId>junit</artifactId>            <version>4.11</version>            <scope>test</scope>        </dependency>        <dependency>            <groupId>net.biancheng.www</groupId>            <artifactId>helloMaven</artifactId>            <version>1.0-SNAPSHOT</version>        </dependency>    </dependencies>    <build>        <pluginManagement>            <plugins>                <plugin>                    <artifactId>maven-clean-plugin</artifactId>                    <version>3.1.0</version>                </plugin>                <plugin>                    <artifactId>maven-resources-plugin</artifactId>                    <version>3.0.2</version>                </plugin>                <plugin>                    <artifactId>maven-compiler-plugin</artifactId>                    <version>3.8.0</version>                </plugin>                <plugin>                    <artifactId>maven-surefire-plugin</artifactId>                    <version>2.22.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>                <plugin>                    <artifactId>maven-site-plugin</artifactId>                    <version>3.7.1</version>                </plugin>                <plugin>                    <artifactId>maven-project-info-reports-plugin</artifactId>                    <version>3.0.0</version>                </plugin>            </plugins>        </pluginManagement>    </build></project>

打开命令控制台,执行如下命令,查看 maven-invoker-plugin 插件绑定的目标。

mvn help:describe -Dplugin=invoker

Maven 命令执行结果如下。

[INFO] Scanning for projects...[INFO][INFO] ------------------< org.apache.maven:standalone-pom >-------------------[INFO] Building Maven Stub Project (No POM) 1[INFO] --------------------------------[ pom ]---------------------------------[INFO][INFO] --- maven-help-plugin:3.2.0:describe (default-cli) @ standalone-pom ---Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-invoker-plugin/maven-metadata.xmlDownloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-invoker-plugin/maven-metadata.xml (888 B at 539 B/s)[INFO] org.apache.maven.plugins:maven-invoker-plugin:3.2.2Name: Apache Maven Invoker PluginDescription: The Maven Invoker Plugin is used to run a set of Maven projects.  The plugin can determine whether each project execution is successful, and  optionally can verify the output generated from a given project execution.Group Id: org.apache.maven.pluginsArtifact Id: maven-invoker-pluginVersion: 3.2.2Goal Prefix: invokerThis plugin has 6 goals:invoker:help  Description: Display help information on maven-invoker-plugin.    Call mvn invoker:help -Ddetail=true -Dgoal=<goal-name> to display parameter    details.invoker:install  Description: Installs the project artifacts of the main build into the    local repository as a preparation to run the sub projects. More precisely,    all artifacts of the project itself, all its locally reachable parent POMs    and all its dependencies from the reactor will be installed to the local    repository.invoker:integration-test  Description: Searches for integration test Maven projects, and executes    each, collecting a log in the project directory, will never fail the build,    designed to be used in conjunction with the verify mojo.invoker:report  Description: Generate a report based on the results of the Maven    invocations. Note: This mojo doesn't fork any lifecycle, if you have a    clean working copy, you have to use a command like mvn clean    integration-test site to ensure the build results are present when this    goal is invoked.  Note: This goal should be used as a Maven report.invoker:run  Description: Searches for integration test Maven projects, and executes    each, collecting a log in the project directory, and outputting the results    to the command line.invoker:verify  Description: Checks the results of maven-invoker-plugin based integration    tests and fails the build if any tests failed.For more information, run 'mvn help:describe [...] -Ddetail'[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time:  4.467 s[INFO] Finished at: 2021-03-05T10:03:15+08:00[INFO] ------------------------------------------------------------------------

由以上执行结果可知,maven-invoker-plugin 插件绑定的 Maven 生命周期阶段为 integration-test 及其以后,所以执行 integration-test 阶段及其以后的都可以触发该插件。

跳转到 D:\maven\helloMaven 目录下,执行如下 Maven 命令。

mvn clean install

执行结果如下。

[INFO] Scanning for projects...[INFO][INFO] --------------------< net.biancheng.www:helloMaven >--------------------[INFO] Building helloMaven 1.0-SNAPSHOT[INFO] --------------------------------[ jar ]---------------------------------[INFO][INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ helloMaven ---[INFO] Deleting d:\maven\helloMaven\target[INFO][INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ helloMaven ---[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent![INFO] skip non existing resourceDirectory d:\maven\helloMaven\src\main\resources[INFO][INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ helloMaven ---[INFO] Changes detected - recompiling the module![WARNING] File encoding has not been set, using platform encoding GBK, i.e. build is platform dependent![INFO] Compiling 2 source files to d:\maven\helloMaven\target\classes[INFO][INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ helloMaven ---[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent![INFO] skip non existing resourceDirectory d:\maven\helloMaven\src\test\resources[INFO][INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ helloMaven ---[INFO] Changes detected - recompiling the module![WARNING] File encoding has not been set, using platform encoding GBK, i.e. build is platform dependent![INFO] Compiling 1 source file to d:\maven\helloMaven\target\test-classes[INFO][INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ helloMaven ---[INFO] Surefire report directory: d:\maven\helloMaven\target\surefire-reports-------------------------------------------------------T E S T S-------------------------------------------------------Running net.biancheng.www.AppTestTests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.008 secResults :Tests run: 1, Failures: 0, Errors: 0, Skipped: 0[INFO][INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ helloMaven ---[INFO] Building jar: d:\maven\helloMaven\target\helloMaven-1.0-SNAPSHOT.jar[INFO][INFO] --- maven-invoker-plugin:3.2.2:run (id-integration-test) @ helloMaven ---[WARNING] File encoding has not been set, using platform encoding GBK, i.e. build is platform dependent![WARNING] Filtering of parent/child POMs is not supported without cloning the projects[INFO] Building: secondMaven\pom.xml[INFO]           secondMaven\pom.xml .............................. SUCCESS (2.6 s)[INFO] Building: thirdMaven\pom.xml[INFO]           thirdMaven\pom.xml ............................... SUCCESS (3.7 s)[INFO] -------------------------------------------------[INFO] Build Summary:[INFO]   Passed: 2, Failed: 0, Errors: 0, Skipped: 0[INFO] -------------------------------------------------[INFO][INFO] --- maven-install-plugin:2.4:install (default-install) @ helloMaven ---[INFO] Installing d:\maven\helloMaven\target\helloMaven-1.0-SNAPSHOT.jar to D:\myRepository\repository\net\biancheng\www\helloMaven\1.0-SNAPSHOT\helloMaven-1.0-SNAPSHOT.jar[INFO] Installing d:\maven\helloMaven\pom.xml to D:\myRepository\repository\net\biancheng\www\helloMaven\1.0-SNAPSHOT\helloMaven-1.0-SNAPSHOT.pom[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time:  9.335 s[INFO] Finished at: 2021-03-05T10:20:26+08:00[INFO] ------------------------------------------------------------------------

!!通过以上执行过程可以看到,在 helloMaven 构建完成后, Invoker 插件对 secondMaven 和 thirdMaven 也进行了构建。

注意:secondMaven 和 thirdMaven 是否依赖于 helloMaven,不会影响 Invoker 插件是否对它们进行构建。即使 secondMaven 和 thirdMaven 都不依赖于 helloMaven,只要在 Invoker 插件中配置了这些项目,Invoker 插件也依然会在 helloMaven 构建完成后,对它们进行构建。

3.0 Maven 依赖传递

1、说明:

Maven 依赖传递是 Maven 的核心机制之一,它能够一定程度上简化 Maven 的依赖配置。本节我们将详细介绍依赖传递及其相关概念。

如下图所示,项目 A 依赖于项目 B,B 又依赖于项目 C,此时 B 是 A 的直接依赖,C 是 A 的间接依赖。

image-20211011084501110

Maven 的依赖传递机制是指:不管 Maven 项目存在多少间接依赖,POM 中都只需要定义其直接依赖,不必定义任何间接依赖,Maven 会动读取当前项目各个直接依赖的 POM,将那些必要的间接依赖以传递性依赖的形式引入到当前项目中。Maven 的依赖传递机制能够帮助用户一定程度上简化 POM 的配置。

基于 A、B、C 三者的依赖关系,根据 Maven 的依赖传递机制,我们只需要在项目 A 的 POM 中定义其直接依赖 B,在项目 B 的 POM 中定义其直接依赖 C,Maven 会解析 A 的直接依赖 B的 POM ,将间接依赖 C 以传递性依赖的形式引入到项目 A 中。

通过这种依赖传递关系,可以使依赖关系树迅速增长到一个很大的量级,很有可能会出现依赖重复,依赖冲突等情况,Maven 针对这些情况提供了如下功能进行处理。

  • 依赖范围(Dependency scope)
  • 依赖调解(Dependency mediation)
  • 可选依赖(Optional dependencies)
  • 排除依赖(Excluded dependencies)
  • 依赖管理(Dependency management)

2、依赖范围:

首先,我们要知道 Maven 在对项目进行编译、测试和运行时,会分别使用三套不同的 classpath。Maven 项目构建时,在不同阶段引入到 classpath 中的依赖时不同的。例如编译时,Maven 会将与编译相关的依赖引入到编译 classpath 中;测试时,Maven 会将与测试相关的的依赖引入到测试 classpath 中;运行时,Maven 会将与运行相关的依赖引入到运行 classpath 中。

我们可以在 POM 的依赖声明使用 scope 元素来控制依赖与三种 classpath(编译 classpath、测试 classpath、运行 classpath )之间的关系,这就是依赖范围。

Maven 具有以下 6 中常见的依赖范围,如下表所示。

依赖范围描述
compile编译依赖范围,scope 元素的缺省值。使用此依赖范围的 Maven 依赖,对于三种 classpath 均有效,即该 Maven 依赖在上述三种 classpath 均会被引入。例如,log4j 在编译、测试、运行过程都是必须的。
test测试依赖范围。使用此依赖范围的 Maven 依赖,只对测试 classpath 有效。例如,Junit 依赖只有在测试阶段才需要。
provided已提供依赖范围。使用此依赖范围的 Maven 依赖,只对编译 classpath 和测试 classpath 有效。例如,servlet-api 依赖对于编译、测试阶段而言是需要的,但是运行阶段,由于外部容器已经提供,故不需要 Maven 重复引入该依赖。
runtime运行时依赖范围。使用此依赖范围的 Maven 依赖,只对测试 classpath、运行 classpath 有效。例如,JDBC 驱动实现依赖,其在编译时只需 JDK 提供的 JDBC 接口即可,只有测试、运行阶段才需要实现了 JDBC 接口的驱动。
system系统依赖范围,其效果与 provided 的依赖范围一致。其用于添加非 Maven 仓库的本地依赖,通过依赖元素 dependency 中的 systemPath 元素指定本地依赖的路径。鉴于使用其会导致项目的可移植性降低,一般不推荐使用。
import导入依赖范围,该依赖范围只能与 dependencyManagement 元素配合使用,其功能是将目标 pom.xml 文件中 dependencyManagement 的配置导入合并到当前 pom.xml 的 dependencyManagement 中。

依赖范围与三种 classpath 的关系一览表,如下所示。

依赖范围编译 classpath测试 classpath运行 classpath例子
compilelog4j
test--junit
provided-servlet-api
runtime--JDBC-driver
system-非 Maven 仓库的本地依赖

3、依赖范围对传递依赖的影响

项目 A 依赖于项目 B,B 又依赖于项目 C,此时我们可以将 A 对于 B 的依赖称之为第一直接依赖,B 对于 C 的依赖称之为第二直接依赖。

B 是 A 的直接依赖,C 是 A 的间接依赖,根据 Maven 的依赖传递机制,间接依赖 C 会以传递性依赖的形式引入到 A 中,但这种引入并不是无条件的,它会受到依赖范围的影响。

传递性依赖的依赖范围受第一直接依赖和第二直接依赖的范围影响,如下表所示。

compiletestprovidedruntime
compilecompile--runtime
testtest--test
providedprovided-providedprovided
runtimeruntime--runtime

注:上表中,左边第一列表示第一直接依赖的依赖范围,上边第一行表示第二直接依赖的依赖范围。交叉部分的单元格的取值为传递性依赖的依赖范围,若交叉单元格取值为“-”,则表示该传递性依赖不能被传递。

通过上表,可以总结出以下规律:

  • 当第二直接依赖的范围是 compile 时,传递性依赖的范围与第一直接依赖的范围一致;
  • 当第二直接依赖的范围是 test 时,传递性依赖不会被传递;
  • 当第二直接依赖的范围是 provided 时,只传递第一直接依赖的范围也为 provided 的依赖,且传递性依赖的范围也为 provided;
  • 当第二直接依赖的范围是 runtime 时,传递性依赖的范围与第一直接依赖的范围一致,但 compile 例外,此时传递性依赖的范围为 runtime。

4、依赖调节:

Maven 的依赖传递机制可以简化依赖的声明,用户只需要关心项目的直接依赖,而不必关心这些直接依赖会引入哪些间接依赖。但当一个间接依赖存在多条引入路径时,为了避免出现依赖重复的问题,Maven 通过依赖调节来确定间接依赖的引入路径。

依赖调节遵循以下两条原则:

  1. 引入路径短者优先
  2. 先声明者优先

以上两条原则,优先使用第一条原则解决,第一条原则无法解决,再使用第二条原则解决。

1)引入路径短者优先

引入路径短者优先,顾名思义,当一个间接依赖存在多条引入路径时,引入路径短的会被解析使用。

例如,A 存在这样的依赖关系:
A->B->C->D(1.0)
A->X->D(2.0)

D 是 A 的间接依赖,但两条引入路径上有两个不同的版本,很显然不能同时引入,否则造成重复依赖的问题。根据 Maven 依赖调节的第一个原则:引入路径短者优先,D(1.0)的路径长度为 3,D(2.0)的路径长度为 2,因此间接依赖 D(2.0)将从 A->X->D(2.0) 路径引入到 A 中。

2)先声明者优先

先声明者优先,顾名思义,在引入路径长度相同的前提下,POM 文件中依赖声明的顺序决定了间接依赖会不会被解析使用,顺序靠前的优先使用。

例如,A 存在以下依赖关系:
A->B->D(1.0)
A->X->D(2.0)

D 是 A 的间接依赖,其两条引入路径的长度都是 2,此时 Maven 依赖调节的第一原则已经无法解决,需要使用第二原则:先声明者优先。

A 的 POM 文件中配置如下。

<dependencies>    ...          <dependency>        ...        <artifactId>B</artifactId>               ...    </dependency>    ...    <dependency>        ...        <artifactId>X</artifactId>        ...    </dependency>    ...</dependencies>

有以上配置可以看出,由于 B 的依赖声明比 X 靠前,所以间接依赖 D(1.0)将从 A->B->D(1.0) 路径引入到 A 中。

5、排除依赖:

假设存在这样的依赖关系,A 依赖于 B,B 依赖于 X,B 又依赖于 Y。B 实现了两个特性,其中一个特性依赖于 X,另一个特性依赖于 Y,且两个特性是互斥的关系,用户无法同时使用两个特性,所以 A 需要排除 X,此时就可以在 A 中将间接依赖 X 排除。

排除依赖是通过在 A 中使用 exclusions 元素实现的,该元素下可以包含若干个 exclusion 子元素,用于排除若干个间接依赖,示例代码如下。

<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>net.biancheng.www</groupId>    <artifactId>A</artifactId>    <version>1.0-SNAPSHOT</version>    <dependencies>        <dependency>            <groupId>net.biancheng.www</groupId>            <artifactId>B</artifactId>            <version>1.0-SNAPSHOT</version>            <exclusions>                <!-- 设置排除 -->                <!-- 排除依赖必须基于直接依赖中的间接依赖设置为可以依赖为 false -->                <!-- 设置当前依赖中是否使用间接依赖 -->                <exclusion>                    <!--设置具体排除-->                    <groupId>net.biancheng.www</groupId>                    <artifactId>X</artifactId>                </exclusion>            </exclusions>        </dependency>    </dependencies></project>

关于 exclusions 元素及排除依赖说明如下:

  • 排除依赖是控制当前项目是否使用其直接依赖传递下来的接间依赖;
  • exclusions 元素下可以包含若干个 exclusion 子元素,用于排除若干个间接依赖;
  • exclusion 元素用来设置具体排除的间接依赖,该元素包含两个子元素:groupId 和 artifactId,用来确定需要排除的间接依赖的坐标信息;
  • exclusion 元素中只需要设置 groupId 和 artifactId 就可以确定需要排除的依赖,无需指定版本 version。

6、可选依赖:

与上文的应用场景相同,也是 A 希望排除间接依赖 X,除了在 B 中设置可选依赖外,我们还可以在 B 中将 X 设置为可选依赖。

1)设置可选依赖

在 B 的 POM 关于 X 的依赖声明中使用 optional 元素,将其设置成可选依赖,示例配置如下。

<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>net.biancheng.www</groupId>    <artifactId>B</artifactId>    <packaging>jar</packaging>    <version>1.0-SNAPSHOT</version>    <dependencies>        <dependency>            <groupId>net.biancheng.www</groupId>            <artifactId>X</artifactId>            <version>1.0-SNAPSHOT</version>            <!--设置可选依赖  -->            <optional>true</optional>        </dependency>    </dependencies></project>

关于 optional 元素及可选依赖说明如下:

  • 可选依赖用来控制当前依赖是否向下传递成为间接依赖;
  • optional 默认值为 false,表示可以向下传递称为间接依赖;
  • 若 optional 元素取值为 true,则表示当前依赖不能向下传递成为间接依赖。

7、排除依赖 VS 可选依赖 :

排除依赖和可选依赖都能在项目中将间接依赖排除在外,但两者实现机制却完全不一样。

  • 排除依赖是控制当前项目是否使用其直接依赖传递下来的接间依赖;
  • 可选依赖是控制当前项目的依赖是否向下传递;
  • 可选依赖的优先级高于排除依赖;
  • 若对于同一个间接依赖同时使用排除依赖和可选依赖进行设置,那么可选依赖的取值必须为 false,否则排除依赖无法生效。

3.1 Maven 继承

1、说明:

1)背景:
  • 我们知道,Maven 的依赖传递机制可以一定程度上简化 POM 的配置,但这仅限于存在依赖关系的项目或模块中。当一个项目的多个模块都依赖于相同 jar 包的相同版本,且这些模块之间不存在依赖关系,这就导致同一个依赖需要在多个模块中重复声明,这显然是不可取的,大量的前人经验告诉我们,重复往往意味着更多的劳动和更高的潜在风险。

    在 Java 面向对象中,我们可以建立一种类的父子结构,然后在父类中声明一些字段和方法供子类继承,这样就可以一定程度上消除重复,做到“一处声明,多处使用”。在 Maven 的世界中,也有类似的机制,它就是 POM 继承。

2)概念:
  • Maven 在设计时,借鉴了 Java 面向对象中的继承思想,提出了 POM 继承思想。当一个项目包含多个模块时,可以在该项目中再创建一个父模块,并在其 POM 中声明依赖,其他模块的 POM 可通过继承父模块的 POM 来获得对相关依赖的声明。对于父模块而言,其目的是为了消除子模块 POM 中的重复配置,其中不包含有任何实际代码,因此父模块 POM 的打包类型(packaging)必须是 pom。

2、示例:

如图 1 所示,一个项目中存在如下多个模块。

image-20211011091041172

如上图所示:

  • App-UI-WAR 依赖于 App-Core-lib 和 App-Data-lib。
  • Root 是 App-Core-lib 和 App-Data-lib 的父模块。
  • Root 在它的依赖部分定义了 junit 4.9、mysql-connector-java 5.1.18 以及 c3p0 0.9.1 作为其依赖。

App-UI-WAR 的 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>net.biancheng.www</groupId>    <artifactId>App-UI-WAR</artifactId>    <version>1.0</version>    <dependencies>        <!-- 依赖 App-Core-lib-->        <dependency>            <groupId>net.biancheng.www</groupId>            <artifactId>App-Core-lib</artifactId>            <version>1.0</version>        </dependency>        <!-- 依赖 App-Data-lib-->        <dependency>            <groupId>net.biancheng.www</groupId>            <artifactId>App-Data-lib</artifactId>            <version>1.0</version>        </dependency>    </dependencies></project>
父模块 POM 配置

父模块 Root 的 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>net.biancheng.www</groupId>    <artifactId>Root</artifactId>    <version>1.0</version>    <!--定义的父类 POM 打包类型使pom  -->    <packaging>pom</packaging>       <dependencies>        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>            <version>4.9</version>            <scope>test</scope>        </dependency>        <dependency>            <groupId>mysql</groupId>            <artifactId>mysql-connector-java</artifactId>            <version>5.1.18</version>            <scope>runtime</scope>        </dependency>        <dependency>            <groupId>c3p0</groupId>            <artifactId>c3p0</artifactId>            <version>0.9.1</version>        </dependency>    </dependencies></project>

在父模块 Root 的 pom.xml 中,其打包类型(packaging)为 pom,并声明了 3 个依赖:junit 4.9、mysql-connector-java 5.1.18 以及 c3p0 0.9.1 。

子模块 POM 配置

App-Core-lib 的 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>net.biancheng.www</groupId>    <artifactId>App-Core-lib</artifactId>    <version>1.0</version>    <parent>        <groupId>net.biancheng.www</groupId>        <artifactId>Root</artifactId>        <version>1.0</version>        <relativePath>../Root</relativePath>    </parent>    <dependencies>        <dependency>            <groupId>log4j</groupId>            <artifactId>log4j</artifactId>            <version>1.2.17</version>        </dependency>    </dependencies></project>

App-Data-lib 的 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>net.biancheng.www</groupId>    <artifactId>App-Data-lib</artifactId>    <version>1.0</version>    <parent>        <groupId>net.biancheng.www</groupId>        <artifactId>Root</artifactId>        <version>1.0</version>        <!-- <relativePath>../Root</relativePath> -->    </parent></project>

在子模块 App-Core-lib 和 App-Data-lib 的 pom.xml 中,使用 parent 元素声明父模块,其子元素如下表:

元素描述是否必需
groupId父模块的项目组 id。
artifactId父模块 id。
version父模块版本。
relativePath父模块 POM 的相对路径,默认值为 …/pom.xml。 项目构建时,Maven 会先根据 relativePath 查找父模块 POM,如果找不到,再从本地仓库或远程仓库中查找。

子模块的 POM 中,当前模块的 groupId 和 version 元素可以省略,但这并不意味着当前模块没有 groupId 和 version,子模块会隐式的从父模块中继承这两个元素,即由父模块控制子模块的公司组织 id 以及版本,这样可以简化 POM 的配置。

查看继承依赖项

在 App-Core-lib 和 App-Data-lib 两个子模块的 pom.xml 中,只有 App-Core-lib 声明了一个依赖: log4j 1.2.17。那么如何验证子模块是否继承了父模块 POM 中声明的依赖项呢?

下面我们需要用到一个插件:maven-dependency-plugin,它可以帮助我们分析项目依赖,其插件目标 dependency:list 能够列出项目最终解析到的依赖列表,dependency:tree 能够进一步的描绘项目依赖树。

  1. 打开命令行窗口,跳转到子模块 App-Core-lib 的目录下,执行以下命令,查看该模块依赖列表。

    mvn dependency:list
    

    命令执行结果如下。

    [INFO] Scanning for projects...[INFO][INFO] -------------------< net.biancheng.www:App-Core-lib >-------------------[INFO] Building App-Core-lib 1.0[INFO] --------------------------------[ jar ]---------------------------------[INFO][INFO] --- maven-dependency-plugin:2.8:list (default-cli) @ App-Core-lib ---[INFO][INFO] The following files have been resolved:[INFO]    junit:junit:jar:4.9:compile[INFO]    log4j:log4j:jar:1.2.17:compile[INFO]    c3p0:c3p0:jar:0.9.1:compile[INFO]    mysql:mysql-connector-java:jar:5.1.18:runtime[INFO]    org.hamcrest:hamcrest-core:jar:1.1:compile[INFO][INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time:  0.921 s[INFO] Finished at: 2021-04-14T15:09:18+08:00[INFO] ------------------------------------------------------------------------
    

    可以看到,App-Core-lib 有 5 个依赖项,其中 junit 4.9、mysql-connector-java 5.1.18 以及 c3p0 0.9.1 是从父模块 Root 中继承的;log4j 1.2.17 是该模块本身的 POM 中声明的;hamcrest 1.1 是 junit 4.9 传递下来的依赖项。

    1. 在命令行窗口中,跳转到子模块 App-Data-lib 的目录下,执行以下命令,查看该模块依赖列表。
    mvn dependency:list
    

    命令执行结果如下。

    [INFO] Scanning for projects...[INFO][INFO] -------------------< net.biancheng.www:App-Data-lib >-------------------[INFO] Building App-Data-lib 1.0[INFO] --------------------------------[ jar ]---------------------------------[INFO][INFO] --- maven-dependency-plugin:2.8:list (default-cli) @ App-Data-lib ---[INFO][INFO] The following files have been resolved:[INFO]    junit:junit:jar:4.9:compile[INFO]    c3p0:c3p0:jar:0.9.1:compile[INFO]    mysql:mysql-connector-java:jar:5.1.18:runtime[INFO]    org.hamcrest:hamcrest-core:jar:1.1:compile[INFO][INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time:  0.938 s[INFO] Finished at: 2021-04-14T15:37:28+08:00[INFO] ------------------------------------------------------------------------
    

    可以看到,App-Data-lib 有 4 个依赖项,其中 junit 4.9、mysql-connector-java 5.1.18 以及 c3p0 0.9.1 是从父模块 Root 中继承的;hamcrest 1.1 是 junit 4.9 传递下来的依赖项。

可继承的 POM 元素

在上面的例子中,我们可以看出 groupId、artifactId 以及项目的依赖配置 dependencies 是可以被继承的,除了这 3 个元素之外,还有哪些元素可以被继承呢?

Maven 可通过继承获得 POM 元素,如下表。

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

3.2 dependencyManagement:管理Maven依赖

1、背景:

我们知道,子模块可以通过继承获得父模块中声明的全部依赖,这样虽然避免了在各个子模块 POM 中重复进行依赖声明,但也极有可能造成子模块中引入一些不必要的依赖。为此 Maven 引入了 dependencyManagement 来对依赖进行管理。

2、依赖管理:

Maven 可以通过 dependencyManagement 元素对依赖进行管理,它具有以下 2 大特性:

  • 在该元素下声明的依赖不会实际引入到模块中,只有在 dependencies 元素下同样声明了该依赖,才会引入到模块中。
  • 该元素能够约束 dependencies 下依赖的使用,即 dependencies 声明的依赖若未指定版本,则使用 dependencyManagement 中指定的版本,否则将覆盖 dependencyManagement 中的版本。

例如,修改 App-Data-lib 模块的 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <!--由于不是继承,所以必须重新添加 groupId 和 version-->    <groupId>net.biancheng.www</groupId>    <artifactId>App-Data-lib</artifactId>    <version>1.0</version>    <!--dependencyManagement 标签用于控制子模块的依赖版本等信息 -->    <!-- 该标签只用来控制版本,不能将依赖引入 -->    <dependencyManagement>        <dependencies>            <dependency>                <groupId>log4j</groupId>                <artifactId>log4j</artifactId>                <!--引用的properties标签中定义的属性 -->                <version>1.2.17</version>            </dependency>            <dependency>                <groupId>junit</groupId>                <artifactId>junit</artifactId>                <!--引用的properties标签中定义的属性 -->                <version>4.9</version>                <!-- <scope>test</scope> -->            </dependency>            <dependency>                <groupId>mysql</groupId>                <artifactId>mysql-connector-java</artifactId>                <!--引用的properties标签中定义的属性 -->                <version>5.1.18</version>                <scope>runtime</scope>            </dependency>            <dependency>                <groupId>c3p0</groupId>                <artifactId>c3p0</artifactId>                <!--引用的properties标签中定义的属性 -->                <version>0.9.1</version>            </dependency>        </dependencies>    </dependencyManagement>    <!--声明依赖-->    <dependencies>        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>        </dependency>    </dependencies></project>

在以上配置中,由于 dependencyManagement 元素中已经定义完整的依赖声明,所以在 dependencies 元素中声明的依赖只配置了 groupId 和 artifactId,省略了 version 和 scope。

在实际的开发过程中,dependencyManagement 很少会单独使用,通常它需要与 Maven 继承或依赖范围 import 配合使用才能展现它的优势。

3、继承依赖管理:

由于 dependencyManagement 元素是可以被继承的,因此我们可以在父模块 POM 中使用 dependencyManagement 元素声明所有子模块的依赖,然后在各个子模块 POM 使用 dependencies 元素声明实际用到的依赖即可。这样既可以让子模块能够继承父模块的依赖配置,还能避免将不必要的依赖引入到子模块中。

  1. 修改父模块 Root 的 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>net.biancheng.www</groupId>    <artifactId>Root</artifactId>    <version>1.0</version>    <!--定义的父类pom.xml 打包类型使pom -->    <packaging>pom</packaging>    <properties>        <!-- 定义一些 maven 变量 -->        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>        <log4j.version>1.2.17</log4j.version>        <junit.version>4.9</junit.version>        <system.version>1.0</system.version>        <mysql.connector.version>5.1.18</mysql.connector.version>        <c3p0.version>0.9.1</c3p0.version>    </properties>    <!--dependencyManagement 标签用于控制子模块的依赖版本等信息 -->    <!-- 该标签只用来控制版本,不能将依赖引入 -->    <dependencyManagement>        <dependencies>            <dependency>                <groupId>log4j</groupId>                <artifactId>log4j</artifactId>                <!--引用的properties标签中定义的变量 -->                <version>${log4j.version}</version>            </dependency>            <dependency>                <groupId>junit</groupId>                <artifactId>junit</artifactId>                <!--引用的properties标签中定义的变量 -->                <version>${junit.version}</version>                <!-- <scope>test</scope> -->            </dependency>            <dependency>                <groupId>mysql</groupId>                <artifactId>mysql-connector-java</artifactId>                <!--引用的properties标签中定义的变量 -->                <version>${mysql.connector.version}</version>                <scope>runtime</scope>            </dependency>            <dependency>                <groupId>c3p0</groupId>                <artifactId>c3p0</artifactId>                <!--引用的properties标签中定义的变量 -->                <version>${c3p0.version}</version>            </dependency>        </dependencies>    </dependencyManagement></project>

注:以上配置中,将所有依赖的版本信息以 Maven 变量(properties)的形式提取出来,这样不仅消除了一些重复,也使得各个依赖的版本信息更加明显,便于管理。

在父模块 Root 中使用 dependencyManagement 元素声明的依赖,既不会给 Root 模块引入依赖,也不会给其子模块引入依赖,但这段配置是可以被继承的。

  1. 修改子模块 App-Core-lib 的 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <artifactId>App-Core-lib</artifactId>    <parent>        <groupId>net.biancheng.www</groupId>        <artifactId>Root</artifactId>        <version>1.0</version>        <relativePath>../Root</relativePath>    </parent>    <dependencies>        <dependency>            <groupId>log4j</groupId>            <artifactId>log4j</artifactId>        </dependency>        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>        </dependency>        <dependency>            <groupId>mysql</groupId>            <artifactId>mysql-connector-java</artifactId>        </dependency>        <dependency>            <groupId>c3p0</groupId>            <artifactId>c3p0</artifactId>        </dependency>    </dependencies>    <distributionManagement>        <repository>            <id>bianchengbang_Release_hosted</id>            <url>http://localhost:8082/nexus/content/repositories/bianchengbang_Release_hosted/</url>        </repository>        <snapshotRepository>            <id>Snapshot</id>            <url>http://localhost:8082/nexus/content/repositories/bianchengbang_Snapshot_hosted/</url>        </snapshotRepository>    </distributionManagement></project>
    
  2. 修改子模块 App-Data-lib 的 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <artifactId>App-Data-lib</artifactId>    <parent>        <groupId>net.biancheng.www</groupId>        <artifactId>Root</artifactId>        <version>1.0</version>    </parent>       <dependencies>        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>        </dependency>    </dependencies></project>
    

    在子模块 App-Core-lib 和 App-Data-lib 的 POM 中,所有在 dependencies 元素中声明的依赖都只配置了 groupId 和 artifactId,省去了 version 和 scope。之所以能够省略这些信息,是因为它们继承了父模块 Root 中 dependencyManagement 的配置,其完整的依赖声明已经包含在父模块的 POM 中,子模块只需要配置 groupId 和 artifactId 就能获得相应的依赖信息,从而引入正确的依赖。

    使用这种依赖管理机制似乎并不能减少太多 POM 配置,但我们仍然推荐使用这种方式,其原因主要有 2 个:

    • 在父模块中使用 dependencyManagement 声明依赖能够统一项目内依赖的版本,子模块无须声明版本,也就不会出现多个子模块使用同一依赖项版本不一致的情况,降低依赖冲突的几率。
    • dependencyManagement 声明的依赖不会被实际引入,子模块需要什么依赖就自己引入,增加了灵活性,避免引入一些不必要的依赖。

4、导入依赖管理(import):

Maven 依赖传递 一节介绍依赖范围时,提到了一个名为 import 的依赖范围,之所以要放在这介绍是因为 import 依赖范围只能与 dependencyManagement 元素配合使用才会有效,其功能是将目标 pom.xml 中的 dependencyManagement 配置导入合并到当前 pom.xml 的 dependencyManagement 中。

例如,App-Data-lib 模块想要使用 Root 模块中的 dependencyManagement 配置,除了通过继承或者直接复制这两种方式之外,还可以使用 import 依赖范围将其导入,具体配置如下。

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <!--由于不是继承,所以必须重新添加 groupId 和 version-->    <groupId>net.biancheng.www</groupId>    <artifactId>App-Data-lib</artifactId>    <version>1.0</version>    <!--定义依赖管理-->    <dependencyManagement>        <dependencies>            <!--导入依赖管理配置-->            <dependency>                <groupId>net.biancheng.www</groupId>                <artifactId>Root</artifactId>                <version>1.0</version>                <!--依赖范围为 import-->                <scope>import</scope>                <!--类型一般为pom-->                <type>pom</type>            </dependency>        </dependencies>    </dependencyManagement>    <!--声明依赖-->    <dependencies>        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>        </dependency>    </dependencies></project>

以上配置中,由于 import 依赖范围的特殊性,一般都是指向打包类型为 pom 的模块,所以 type 元素的值一般为 pom。

若存在多个模块,它们使用的依赖版本都是一致的,则就可以定义一个使用 dependencyManagement 专门管理依赖的 POM,然后在各个模块中导入这些依赖管理配置。

3.3 Maven 聚合

1、背景:

在实际的开发过程中,我们所接触的项目一般都由多个模块组成。在构建项目时,如果每次都按模块一个一个地进行构建会十分得麻烦,Maven 的聚合功能很好的解决了这个问题。

2、示例:

使用 Maven 聚合功能对项目进行构建时,需要在该项目中额外创建一个的聚合模块,然后通过这个模块构建整个项目的所有模块。聚合模块仅仅是帮助聚合其他模块的工具,其本身并无任何实质内容,因此聚合模块中只有一个 POM 文件,不像其他的模块一样包含 src/main/java、src/test/java 等多个目录。

与父模块相似,聚合模块的打包方式(packaging)也是 pom,用户可以在其 POM 中通过 modules 下的 module 子元素来添加需要聚合的模块的目录路径。

修改 Root 模块 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>net.biancheng.www</groupId>    <artifactId>Root</artifactId>    <version>1.0</version>    <!--定义的父类pom.xml 打包类型使pom -->    <packaging>pom</packaging>    <properties>        <!-- 定义一些属性 -->        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>        <log4j.version>1.2.17</log4j.version>        <junit.version>4.9</junit.version>        <system.version>1.0</system.version>        <mysql.connector.version>5.1.18</mysql.connector.version>        <c3p0.version>0.9.1</c3p0.version>    </properties>    <!--dependencyManagement 标签用于控制子模块的依赖版本等信息 -->    <!-- 该标签只用来控制版本,不能将依赖引入 -->    <dependencyManagement>        <dependencies>            <dependency>                <groupId>log4j</groupId>                <artifactId>log4j</artifactId>                <!--引用的properties标签中定义的属性 -->                <version>${log4j.version}</version>            </dependency>            <dependency>                <groupId>junit</groupId>                <artifactId>junit</artifactId>                <!--引用的properties标签中定义的属性 -->                <version>${junit.version}</version>                <!-- <scope>test</scope> -->            </dependency>            <dependency>                <groupId>mysql</groupId>                <artifactId>mysql-connector-java</artifactId>                <!--引用的properties标签中定义的属性 -->                <version>${mysql.connector.version}</version>                <scope>runtime</scope>            </dependency>            <dependency>                <groupId>c3p0</groupId>                <artifactId>c3p0</artifactId>                <!--引用的properties标签中定义的属性 -->                <version>${c3p0.version}</version>            </dependency>        </dependencies>    </dependencyManagement>    <!--添加需要聚合的模块-->    <modules>        <module>../App-Core-lib</module>        <module>../App-Data-lib</module>        <module>../App-UI-WAR</module>    </modules></project>

打开命令行窗口,跳转到 Root 模块所在目录,执行以下 Maven 命令,对 Root 进行构建。

mvn clean install

命令直接结果如下图。

image-20211011230244464

聚合模块在构建时,Maven 会先解析聚合模块的 POM、分析需要构建的模块,并根据这些模块之间的关系计算出构建顺序,然后根据这个顺序依次构建各个模块。

构建完成后输出的是一个项目构建的小结报告,该报告中包括各个模块构建成功与否、构建花费的时间、以及整个构建构成所花费的时间等信息。

3、聚合和集成的关系:

在实际的项目中,一个模块往往既是聚合模块又是其他项目的父模块,那么 Maven 的继承和聚合的关系是如何的呢?

Maven 的继承和聚合的目的不同,继承的目的是为了消除 POM 中的重复配置,聚合的目的是为了方便快速的构建项目。

对于继承中的父模块来说,它跟本不知道那些模块继承了它,但子模块都知道自己的父模块是谁。

对于聚合模块来说,它知道哪些模块被聚合了,但那些被聚合的模块根本不知道聚合模块的存在。

两者在结构和形式上还是有一定的共同点的,最直观的就是两者的打包方式都是 pom,两者除了 POM 外都没有实际的代码内容。

3.4 pluginManagement:管理Maven插件

1、背景:

Maven 使用 dependencyManagement 对依赖进行管理,与之类似地,Maven 中还提供了一个名为 pluginManagement 的元素,它可以帮助用户管理 Maven 插件。

2、插件管理:

pluginManagement 元素与 dependencyManagement 元素的原理十分相似,在 pluginManagement 元素中可以声明插件及插件配置,但不会发生实际的插件调用行为,只有在 POM 中配置了真正的 plugin 元素,且其 groupId 和 artifactId 与 pluginManagement 元素中配置的插件匹配时,pluginManagement 元素的配置才会影响到实际的插件行为。

例如,在 App-Data-lib 模块中使用 pluginManagement 元素管理 maven-source-plugin 插件,并将其插件目标 jar-no-fork 绑定到 default 生命周期的 verify 阶段上,具体配置如下

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <artifactId>App-Data-lib</artifactId>    <parent>        <groupId>net.biancheng.www</groupId>        <artifactId>Root</artifactId>        <version>1.0</version>    </parent>    <dependencies>        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>        </dependency>    </dependencies>    <!--添加插件管理-->    <build>        <pluginManagement>            <plugins>                <!--声明插件-->                <plugin>                    <groupId>org.apache.maven.plugins</groupId>                    <artifactId>maven-source-plugin</artifactId>                    <version>3.2.1</version>                    <executions>                        <!--将 jar-no-fork 目标绑定到 verify 阶段-->                        <execution>                            <id>www.biancheng.net</id>                            <phase>verify</phase>                            <goals>                                <goal>                                    jar-no-fork                                </goal>                            </goals>                        </execution>                    </executions>                </plugin>            </plugins>        </pluginManagement>    </build></project>

根据以上配置可以看出,使用 pluginManagement 管理插件很简单,只需要将声明插件的配置添加在 pluginManagement 元素中即可。

由于该插件目标是绑定在 verify 阶段上,因此我们只需要执行 verify 或以后的阶段(如 install )即可调用 maven-source-plugin:jar-no-fork 目标。

打开命令行窗口,跳转到 App-Data-lib 的目录下,执行以下命令,尝试调用 maven-source-plugin:jar-no-fork 目标。

mvn clean install

执行结果如下。

[INFO] Scanning for projects...[INFO][INFO] -------------------< net.biancheng.www:App-Data-lib >-------------------[INFO] Building App-Data-lib 1.0[INFO] --------------------------------[ jar ]---------------------------------[INFO][INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ App-Data-lib ---[INFO] Deleting D:\eclipse workSpace4\App-Data-lib\target[INFO][INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ App-Data-lib ---[INFO] Using 'UTF-8' encoding to copy filtered resources.[INFO] skip non existing resourceDirectory D:\eclipse workSpace4\App-Data-lib\src\main\resources[INFO][INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ App-Data-lib ---[INFO] Changes detected - recompiling the module![INFO] Compiling 1 source file to D:\eclipse workSpace4\App-Data-lib\target\classes[INFO][INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ App-Data-lib ---[INFO] Using 'UTF-8' encoding to copy filtered resources.[INFO] skip non existing resourceDirectory D:\eclipse workSpace4\App-Data-lib\src\test\resources[INFO][INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ App-Data-lib ---[INFO] Changes detected - recompiling the module![INFO] Compiling 1 source file to D:\eclipse workSpace4\App-Data-lib\target\test-classes[INFO][INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ App-Data-lib ---[INFO] Surefire report directory: D:\eclipse workSpace4\App-Data-lib\target\surefire-reports-------------------------------------------------------T E S T S-------------------------------------------------------Running net.biancheng.www.App_Data_lib.AppTestTests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.027 secResults :Tests run: 1, Failures: 0, Errors: 0, Skipped: 0[INFO][INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ App-Data-lib ---[INFO] Building jar: D:\eclipse workSpace4\App-Data-lib\target\App-Data-lib-1.0.jar[INFO][INFO] --- maven-install-plugin:2.4:install (default-install) @ App-Data-lib ---[INFO] Installing D:\eclipse workSpace4\App-Data-lib\target\App-Data-lib-1.0.jar to D:\myRepository\repository\net\biancheng\www\App-Data-lib\1.0\App-Data-lib-1.0.jar[INFO] Installing D:\eclipse workSpace4\App-Data-lib\pom.xml to D:\myRepository\repository\net\biancheng\www\App-Data-lib\1.0\App-Data-lib-1.0.pom[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time:  2.469 s[INFO] Finished at: 2021-04-16T09:23:26+08:00[INFO] ------------------------------------------------------------------------

通过以上执行结果,我们看到 maven-source-plugin:jar-no-fork 目标并没有被调用。

在 App-Data-lib 的 POM 文件中添加 plugin 元素声明需要调用的插件。

<project>    ...    <!--添加插件管理-->    <build>        <pluginManagement>          ...        </pluginManagement>                <!-- 声明使用 maven-source-plugin 插件 -->        <plugins>            <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-source-plugin</artifactId>            </plugin>        </plugins>    </build></project>

与依赖管理相似,由于 pluginManagement 元素中已经包含了插件的全部信息,所以当使用 plugins 元素声明插件调用时,只需要声明插件的 groupId 和 artifactId 即可。

再次执行命令 mvn clean install,maven-source-plugin:jar-no-fork 目标被成功调用,如图 1 所示。

image-20211011230653903

3、继承插件依赖

当项目中的多个模块存在相同的插件时,应当将插件配置移动到父模块的 pluginManagement 元素中。即使各个模块对于同一插件的具体配置不尽相同,也应当在父模块中使用 pluginManagement 元素对插件版本进行统一声明。

我们甚至可以将项目中所有插件的版本信息都在父模块的 POM 中声明,子模块中不再配置任何的版本信息,这样不仅可以统一项目的插件版本,还可以避免出现版本冲突或插件不稳定等问题。

例如,我们将 App-Data-lib 中 pluginManagement 元素中的配置内容移动到父模块 Root 的 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>net.biancheng.www</groupId>    <artifactId>Root</artifactId>    <version>1.0</version>    <!--定义的父类pom.xml 打包类型使pom -->    <packaging>pom</packaging>    <properties>        <!-- 定义一些属性 -->        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>        <log4j.version>1.2.17</log4j.version>        <junit.version>4.9</junit.version>        <system.version>1.0</system.version>        <mysql.connector.version>5.1.18</mysql.connector.version>        <c3p0.version>0.9.1</c3p0.version>    </properties>    <!--dependencyManagement 标签用于控制子模块的依赖版本等信息 -->    <!-- 该标签只用来控制版本,不能将依赖引入 -->    <dependencyManagement>        <dependencies>            <dependency>                <groupId>log4j</groupId>                <artifactId>log4j</artifactId>                <!--引用的properties标签中定义的属性 -->                <version>${log4j.version}</version>            </dependency>            <dependency>                <groupId>junit</groupId>                <artifactId>junit</artifactId>                <!--引用的properties标签中定义的属性 -->                <version>${junit.version}</version>                <!-- <scope>test</scope> -->            </dependency>            <dependency>                <groupId>mysql</groupId>                <artifactId>mysql-connector-java</artifactId>                <!--引用的properties标签中定义的属性 -->                <version>${mysql.connector.version}</version>                <scope>runtime</scope>            </dependency>            <dependency>                <groupId>c3p0</groupId>                <artifactId>c3p0</artifactId>                <!--引用的properties标签中定义的属性 -->                <version>${c3p0.version}</version>            </dependency>        </dependencies>    </dependencyManagement>    <!--插件依赖-->    <build>        <pluginManagement>            <plugins>                <plugin>                    <groupId>org.apache.maven.plugins</groupId>                    <artifactId>maven-source-plugin</artifactId>                    <version>3.2.1</version>                    <executions>                        <execution>                            <id>www.biancheng.net parent</id>                            <phase>verify</phase>                            <goals>                                <goal>                                    jar-no-fork                                </goal>                            </goals>                        </execution>                    </executions>                </plugin>            </plugins>        </pluginManagement>    </build></project>

在 App-Data-lib 的 POM 中使用 parent 元素继承 Root ,并声明使用 maven-source-plugin 插件,配置如下。

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <artifactId>App-Data-lib</artifactId>    <parent>        <groupId>net.biancheng.www</groupId>        <artifactId>Root</artifactId>        <version>1.0</version>    </parent>    <dependencies>        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>        </dependency>    </dependencies>    <build>        <plugins>            <!-- 声明使用 maven-source-plugin 插件 -->            <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-source-plugin</artifactId>            </plugin>        </plugins>    </build></project>

打开命令行窗口,跳转到 App-Data-lib 的目录下,执行命令

mvn clean install

执行结果如下图。

image-20211011230834029

3.5 Maven Profile精讲

1、背景:

一个项目通常都会有多个不同的运行环境,例如开发环境,测试环境、生产环境等。而不同环境的构建过程很可能是不同的,例如数据源配置、插件、以及依赖的版本等。每次将项目部署到不同的环境时,都需要修改相应的配置,这样重复的工作,不仅浪费劳动力,还容易出错。为了解决这一问题,Maven 引入了 Profile 的概念,通过它可以为不同的环境定制不同的构建过程。

2、Profile 的类型:

Profile 可以分为 3 个类型,它们的作用范围也各不相同。

类型位置有效范围
Per ProjectMaven 项目的 pom.xml 中只对当前项目有效
Per User用户主目录(%USER_HOME%)/.m2/settings.xml 中对本机上该用户所有 Maven 项目有效
GlobalMaven 安装目录(%MAVEN_HOME%)/conf/settings.xml 中对本机上所有 Maven 项目有效

3、声明 Profile:

Maven 通过 profiles 元素来声明一组 Profile 配置,该元素下可以包含多个 profile 子元素,每个 profile 元素表示一个 Profile 配置。每个 profile 元素中通常都要包含一个 id 子元素,该元素是调用当前 Profile 的标识。

定义 Profile 的一般形式如下:

<profiles>    <profile>        <id>profile id</id>        ....    </profile>    <profile>        <id>profile id</id>        ....    </profile></profiles>

除此之外,Profile 中还可以声明一些其他的 POM 元素,但不同位置的 Profile 所能声明的 POM 元素也是不同的。

  1. 在 pom.xml 中声明的 Profile,由于其能够随着 pom.xml 一起存在,它被提交到代码仓库中,被 Maven 安装到本地仓库或远程仓库中,所以它能够修改或增加很多 POM 元素,其中常用的元素如下表。

    image-20211011233256971
  2. 在 setting.xml 中声明的 Profile 是无法保证能够随着 pom.xml 一起被分发的,因此 Maven 不允许用户在该类型的 Profile 修改或增加依赖或插件等配置信息,它只能声明以下范围较为宽泛的元素。

    • repositories:仓库配置。
    • pluginRepositories:插件仓库配置。
    • properties:键值对,该键值对可以在 pom.xml 中使用。

4、激活 Profile:

Profile 能够在项目构建时,修改 POM 中配置或者添加一些额外的配置元素。用户可以通过多种方式激活 Profile,以实现不同环境使用不同的配置,执行不同的构建过程。

下面我们以一个 Maven 项目为例,分别对以上 6 种激活方式进行介绍。

准备 Maven 项目

  1. 创建一个名为 maven 的项目,并在其 src/main/resources 目录下有 3 个环境 properties 配置文件。
  • env.properties:默认配置文件
  • env.test.properties:测试环境配置文件
  • env.prod.properties:生产环境配置文件
  1. 该项目目录结构如图 1 所示。

    image-20211011233533939
  2. 在 pom.xml 中定义三个不同的 Profile,将 maven-antrun-plugin:run 目标绑定到 default 生命周期的 test 阶段上,以实现在不同的 Profile 中进行不同的操作。

    <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 https://maven.apache.org/xsd/maven-4.0.0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>net.biancheng.www</groupId>    <artifactId>maven</artifactId>    <version>0.0.1-SNAPSHOT</version>    <dependencies>        <!-- junit依赖 -->        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>            <version>4.9</version>            <scope>compile</scope>        </dependency>        <!-- log4j依赖 -->        <dependency>            <groupId>log4j</groupId>            <artifactId>log4j</artifactId>            <version>1.2.17</version>        </dependency>    </dependencies>    <profiles>        <!--test 环境配置  -->        <profile>            <id>test</id>            <activation>                <property>                    <name>env</name>                    <value>test</value>                </property>            </activation>            <build>                <plugins>                    <plugin>                        <groupId>org.apache.maven.plugins</groupId>                        <artifactId>maven-antrun-plugin</artifactId>                        <version>1.3</version>                        <executions>                            <execution>                                <phase>test</phase>                                <goals>                                    <goal>run</goal>                                </goals>                                <configuration>                                    <tasks>                                        <!--输出  -->                                        <echo>使用 env.test.properties,将其配置信息复制到 D:\eclipse workSpace                                            3\maven\target\classes\user.properties 中                                        </echo>                                        <!-- 在 target\calsses 目录下生成user.properties -->                                        <!--  env.test.properties 的内容复制到user.properties中-->                                        <copy file="src/main/resources/env.test.properties"                                              tofile="${project.build.outputDirectory}/user.properties"/>                                    </tasks>                                </configuration>                            </execution>                        </executions>                    </plugin>                </plugins>            </build>        </profile>        <!-- 默认环境配置 -->        <profile>            <id>normal</id>            <build>                <plugins>                    <plugin>                        <groupId>org.apache.maven.plugins</groupId>                        <artifactId>maven-antrun-plugin</artifactId>                        <version>1.3</version>                        <executions>                            <execution>                                <phase>test</phase>                                <goals>                                    <goal>run</goal>                                </goals>                                <configuration>                                    <tasks>                                        <echo>使用 env.properties,将其配置信息复制到 D:\eclipse workSpace                                            3\maven\target\classes\user.properties 中                                        </echo>                                        <!-- 在target\calsses 目录下生成user.properties -->                                        <!--  env.properties 的内容复制到user.properties中-->                                        <copy file="src/main/resources/env.properties"                                              tofile="${project.build.outputDirectory}/user.properties"/>                                    </tasks>                                </configuration>                            </execution>                        </executions>                    </plugin>                </plugins>            </build>        </profile>        <!--生产环境配置  -->        <profile>            <id>prod</id>            <build>                <plugins>                    <plugin>                        <groupId>org.apache.maven.plugins</groupId>                        <artifactId>maven-antrun-plugin</artifactId>                        <version>1.3</version>                        <executions>                            <execution>                                <phase>test</phase>                                <goals>                                    <goal>run</goal>                                </goals>                                <configuration>                                    <tasks>                                        <echo>使用 env.prod.properties,将其配置信息复制到 D:\eclipse workSpace                                            3\maven\target\classes\user.properties 中                                        </echo>                                        <!-- 在target\calsses 目录下生成user.properties -->                                        <!--  env.prod.properties 的内容复制到user.properties中-->                                        <copy file="src/main/resources/env.prod.properties"                                              tofile="${project.build.outputDirectory}/user.properties"/>                                    </tasks>                                </configuration>                            </execution>                        </executions>                    </plugin>                </plugins>            </build>        </profile>    </profiles></project>
    

Profile 可以通过以下 6 种方式激活:

1)命令行激活

我们可以在命令行中使用 mvn 命令行参数 -P 加上 Profile 的 id 来激活 Profile,多个 id 之间使用逗号隔开。例如,激活 test1 和 test2 两个 Profile, 命令如下:

mvn clean install -Ptest1,test2

打开命令行窗口,跳转到 pom.xml 所在的目录,执行以下 mvn 命令,激活 id 为 test 的 Profile。

mvn clean test -Ptest 

执行结果如下。

[INFO] Scanning for projects...[INFO][INFO] ----------------------< net.biancheng.www:maven >-----------------------[INFO] Building maven 0.0.1-SNAPSHOT[INFO] --------------------------------[ jar ]---------------------------------[INFO][INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ maven ---[INFO] Deleting D:\eclipse workSpace 3\maven\target[INFO][INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ maven ---[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent![INFO] Copying 3 resources[INFO][INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ maven ---[INFO] Changes detected - recompiling the module![WARNING] File encoding has not been set, using platform encoding GBK, i.e. build is platform dependent![INFO] Compiling 1 source file to D:\eclipse workSpace 3\maven\target\classes[INFO][INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ maven ---[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent![INFO] Copying 0 resource[INFO][INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ maven ---[INFO] Changes detected - recompiling the module![WARNING] File encoding has not been set, using platform encoding GBK, i.e. build is platform dependent![INFO] Compiling 1 source file to D:\eclipse workSpace 3\maven\target\test-classes[INFO][INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ maven ---[INFO] Surefire report directory: D:\eclipse workSpace 3\maven\target\surefire-reports-------------------------------------------------------T E S T S-------------------------------------------------------Running net.biancheng.www.TestTests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.039 secResults :Tests run: 1, Failures: 0, Errors: 0, Skipped: 0[INFO][INFO] --- maven-antrun-plugin:1.3:run (default) @ maven ---[INFO] Executing tasks     [echo] 使用  env.test.properties,将其配置信息复制到 D:\eclipse workSpace 3\maven\target\classes\user.properties 中     [copy] Copying 1 file to D:\eclipse workSpace 3\maven\target\classes[INFO] Executed tasks[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time:  1.968 s[INFO] Finished at: 2021-03-02T09:28:49+08:00[INFO] ------------------------------------------------------------------------
2)settings.xml 文件显示激活

在本地仓库的 settings.xml 文件中添加如下配置,激活指定的 Profile。

<activeProfiles>    <activeProfile>test</activeProfile></activeProfiles>

Maven 本地仓库的 settings.xml 文件,默认位于 %USER_HOME%/.m2 目录下。

打开命令行窗口,跳转到 pom.xml 所在的目录下,执行以下 mvn 命令。

mvn clean test

执行结果如下。

[INFO] Scanning for projects...[INFO][INFO] ----------------------< net.biancheng.www:maven >-----------------------[INFO] Building maven 0.0.1-SNAPSHOT[INFO] --------------------------------[ jar ]---------------------------------[INFO][INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ maven ---[INFO] Deleting D:\eclipse workSpace 3\maven\target[INFO][INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ maven ---[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent![INFO] Copying 3 resources[INFO][INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ maven ---[INFO] Changes detected - recompiling the module![WARNING] File encoding has not been set, using platform encoding GBK, i.e. build is platform dependent![INFO] Compiling 1 source file to D:\eclipse workSpace 3\maven\target\classes[INFO][INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ maven ---[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent![INFO] Copying 0 resource[INFO][INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ maven ---[INFO] Changes detected - recompiling the module![WARNING] File encoding has not been set, using platform encoding GBK, i.e. build is platform dependent![INFO] Compiling 1 source file to D:\eclipse workSpace 3\maven\target\test-classes[INFO][INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ maven ---[INFO] Surefire report directory: D:\eclipse workSpace 3\maven\target\surefire-reports-------------------------------------------------------T E S T S-------------------------------------------------------Running net.biancheng.www.TestTests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.04 secResults :Tests run: 1, Failures: 0, Errors: 0, Skipped: 0[INFO][INFO] --- maven-antrun-plugin:1.3:run (default) @ maven ---[INFO] Executing tasks     [echo] 使用  env.test.properties,将其配置信息复制到 D:\eclipse workSpace 3\maven\target\classes\user.properties 中     [copy] Copying 1 file to D:\eclipse workSpace 3\maven\target\classes[INFO] Executed tasks[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time:  2.012 s[INFO] Finished at: 2021-03-02T09:56:59+08:00[INFO] ------------------------------------------------------------------------
3)系统属性激活

用户可以配置当某个系统属性存在时,激活指定的 Profile。例如,我们在 id 为 prod 的 profile 元素中添加以下配置,表示当系统属性 user 存在,且值等于 prod 时,自动激活该 Profile。

<activation>      <property>        <name>user</name>        <value>prod</value>    </property></activation>

打开命令行窗口,跳转到 pom.xml 所在的目录。执行命令,其中参数 -D 选项用来指定系统临时属性。

mvn clean test -Duser=prod

执行结果如下。

[INFO] Scanning for projects...[INFO][INFO] ----------------------< net.biancheng.www:maven >-----------------------[INFO] Building maven 0.0.1-SNAPSHOT[INFO] --------------------------------[ jar ]---------------------------------[INFO][INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ maven ---[INFO] Deleting D:\eclipse workSpace 3\maven\target[INFO][INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ maven ---[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent![INFO] Copying 3 resources[INFO][INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ maven ---[INFO] Changes detected - recompiling the module![WARNING] File encoding has not been set, using platform encoding GBK, i.e. build is platform dependent![INFO] Compiling 1 source file to D:\eclipse workSpace 3\maven\target\classes[INFO][INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ maven ---[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent![INFO] Copying 0 resource[INFO][INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ maven ---[INFO] Changes detected - recompiling the module![WARNING] File encoding has not been set, using platform encoding GBK, i.e. build is platform dependent![INFO] Compiling 1 source file to D:\eclipse workSpace 3\maven\target\test-classes[INFO][INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ maven ---[INFO] Surefire report directory: D:\eclipse workSpace 3\maven\target\surefire-reports-------------------------------------------------------T E S T S-------------------------------------------------------Running net.biancheng.www.TestTests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.039 secResults :Tests run: 1, Failures: 0, Errors: 0, Skipped: 0[INFO][INFO] --- maven-antrun-plugin:1.3:run (default) @ maven ---[INFO] Executing tasks     [echo] 使用 env.prod.properties,将其配置信息复制到 D:\eclipse workSpace     [echo]                                                                                     3\maven\target\classes\user.properties 中     [copy] Copying 1 file to D:\eclipse workSpace 3\maven\target\classes[INFO] Executed tasks[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time:  2.036 s[INFO] Finished at: 2021-03-02T10:23:19+08:00[INFO] ------------------------------------------------------------------------
4)操作系统环境激活

Maven 还可以根据操作系统环境自动激活指定的 Profile。例如,将以下配置(本地计算机操作系统环境信息)添加到 pom.xml 文件中的 id 为 normal 的 Profile 中。

<activation>    <os>        <name>Windows 10</name>        <family>Windows</family>        <arch>amd64</arch>        <version>10.0</version>    </os></activation>

打开命令行窗口,跳转到 pom.xml 所在的目录下,执行以下 mvn 命令。

mvn clean test

执行结果如下。

[INFO] Scanning for projects...[INFO][INFO] ----------------------< net.biancheng.www:maven >-----------------------[INFO] Building maven 0.0.1-SNAPSHOT[INFO] --------------------------------[ jar ]---------------------------------[INFO][INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ maven ---[INFO] Deleting D:\eclipse workSpace 3\maven\target[INFO][INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ maven ---[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent![INFO] Copying 3 resources[INFO][INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ maven ---[INFO] Changes detected - recompiling the module![WARNING] File encoding has not been set, using platform encoding GBK, i.e. build is platform dependent![INFO] Compiling 1 source file to D:\eclipse workSpace 3\maven\target\classes[INFO][INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ maven ---[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent![INFO] Copying 0 resource[INFO][INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ maven ---[INFO] Changes detected - recompiling the module![WARNING] File encoding has not been set, using platform encoding GBK, i.e. build is platform dependent![INFO] Compiling 1 source file to D:\eclipse workSpace 3\maven\target\test-classes[INFO][INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ maven ---[INFO] Surefire report directory: D:\eclipse workSpace 3\maven\target\surefire-reports-------------------------------------------------------T E S T S-------------------------------------------------------Running net.biancheng.www.TestTests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.044 secResults :Tests run: 1, Failures: 0, Errors: 0, Skipped: 0[INFO][INFO] --- maven-antrun-plugin:1.3:run (default) @ maven ---[INFO] Executing tasks     [echo] 使用 env.properties,将其配置信息复制到 D:\eclipse workSpace     [echo]                                                                                     3\maven\target\classes\user.properties 中     [copy] Copying 1 file to D:\eclipse workSpace 3\maven\target\classes[INFO] Executed tasks[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time:  2.025 s[INFO] Finished at: 2021-03-02T10:46:12+08:00[INFO] ------------------------------------------------------------------------
5)文件存在与否激活

Maven 可以根据某些文件存在与否,来决定是否激活 Profile。例如,在 id 为 prod 的 Profile 中添加以下配置,该配置表示当 env.prod.properties 文件存在,且 env.test.properties 文件不存在时,激活该 Profile。

<activation>        <file>            <exists>./src/main/resources/env.prod.properties</exists>            <missing>./src/main/resources/env.test.properties</missing>        </file></activation>

将 env.test.properties 从项目中删除,打开命令行窗口,跳转到 pom.xml 所在目录,执行以下命令。

mvn clean test 

执行结果如下。

[INFO] Scanning for projects...[INFO][INFO] ----------------------< net.biancheng.www:maven >-----------------------[INFO] Building maven 0.0.1-SNAPSHOT[INFO] --------------------------------[ jar ]---------------------------------[INFO][INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ maven ---[INFO][INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ maven ---[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent![INFO] Copying 2 resources[INFO][INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ maven ---[INFO] Changes detected - recompiling the module![WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent![INFO] Compiling 1 source file to D:\eclipse workSpace4\maven\target\classes[INFO][INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ maven ---[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent![INFO] skip non existing resourceDirectory D:\eclipse workSpace4\maven\src\test\resources[INFO][INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ maven ---[INFO] Changes detected - recompiling the module![WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent![INFO] Compiling 1 source file to D:\eclipse workSpace4\maven\target\test-classes[INFO][INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ maven ---[INFO] Surefire report directory: D:\eclipse workSpace4\maven\target\surefire-reports-------------------------------------------------------T E S T S-------------------------------------------------------Running net.biancheng.www.AppTestTests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.035 secResults :Tests run: 1, Failures: 0, Errors: 0, Skipped: 0[INFO][INFO] --- maven-antrun-plugin:1.3:run (default) @ maven ---[INFO] Executing tasks     [echo] 使用 env.prod.properties,将其配置信息复制到 D:\eclipse workSpace     [echo]                                             3\maven\target\classes\user.properties 中     [copy] Copying 1 file to D:\eclipse workSpace4\maven\target\classes[INFO] Executed tasks[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time:  2.197 s[INFO] Finished at: 2021-04-21T15:12:59+08:00[INFO] ------------------------------------------------------------------------
6)默认激活

我们可以在声明 Profile 时,指定其默认激活。例如,在 id 为 normal 的 Profile 中添加以下配置,指定该 Profile 默认激活。

<activation>    <activeByDefault>true</activeByDefault></activation>

打开命令行窗口,跳转到 pom.xml 所在目录,执行以下命令。

mvn clean test 

执行结果如下。

[INFO] Scanning for projects...[INFO][INFO] ----------------------< net.biancheng.www:maven >-----------------------[INFO] Building maven 0.0.1-SNAPSHOT[INFO] --------------------------------[ jar ]---------------------------------[INFO][INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ maven ---[INFO] Deleting D:\eclipse workSpace4\maven\target[INFO][INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ maven ---[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent![INFO] Copying 2 resources[INFO][INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ maven ---[INFO] Changes detected - recompiling the module![WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent![INFO] Compiling 1 source file to D:\eclipse workSpace4\maven\target\classes[INFO][INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ maven ---[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent![INFO] skip non existing resourceDirectory D:\eclipse workSpace4\maven\src\test\resources[INFO][INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ maven ---[INFO] Changes detected - recompiling the module![WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent![INFO] Compiling 1 source file to D:\eclipse workSpace4\maven\target\test-classes[INFO][INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ maven ---[INFO] Surefire report directory: D:\eclipse workSpace4\maven\target\surefire-reports-------------------------------------------------------T E S T S-------------------------------------------------------Running net.biancheng.www.AppTestTests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.038 secResults :Tests run: 1, Failures: 0, Errors: 0, Skipped: 0[INFO][INFO] --- maven-antrun-plugin:1.3:run (default) @ maven ---[INFO] Executing tasks     [echo] 使用 env.prod.properties,将其配置信息复制到 D:\eclipse workSpace     [echo]                                             3\maven\target\classes\user.properties 中     [copy] Copying 1 file to D:\eclipse workSpace4\maven\target\classes[INFO] Executed tasks[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time:  1.986 s[INFO] Finished at: 2021-04-21T15:24:59+08:00[INFO] ------------------------------------------------------------------------

3.6 Maven 镜像(mirror)

1、背景:

如果一个仓库 A 可以提供另一个仓库 B 的所有内容,那么就可以认为仓库 A 是仓库 B 的一个镜像。即仓库 B 中的任何一个构件都能从它的镜像中获取。

2、使用镜像代替中央仓库:

国内开发人员由于网络原因,直接从中央仓库下载构件时,速度较慢或不稳定,我们通常会使用中央仓库的国内镜像站来解决该问题。

配置 Maven 镜像的方法也非常的简单,我们只需要在 Maven 安装目录中 setting.xml 文件的 mirrors 节点中,使用 mirror 标签添加镜像的相关信息即可。

目前国内使用最多,最稳定的中央仓库镜像分别是由阿里云华为云提供的,它们的地址配置如下。

1)阿里云镜像地址
<mirror>    <id>aliyun</id>    <mirrorOf>central</mirrorOf>    <name>aliyun</name>    <url>https://maven.aliyun.com/repository/public</url></mirror>
2)华为云镜像地址
<mirror>    <id>huaweicloud</id>    <name>mirror from maven huaweicloud</name>    <mirrorOf>central</mirrorOf>    <url>https://repo.huaweicloud.com/repository/maven/</url></mirror>

3、镜像与 Maven 私服配合使用

镜像通常会和 Maven 私服配合使用,由于 Maven 私服可以代理所有外部的公共仓库(包括中央仓库),因此对于组织内部的用户来说,使用一个私服就相当于使用了所有需要的外部仓库,这样就可以将配置集中到私服中,简化 Maven 本身的配置。这种情况下,用户所有所需的构件都可以从私服中获取,此时私服就是所有仓库的镜像。

<srttings>...    <mirrors>        <mirror>            <id>nexus</id>            <mirrorOf>*</mirrorOf>            <name>nexus</name>            <url>http://localhost:8082/nexus/content/groups/bianchengbang_repository_group/</url>        </mirror>    </mirrors>...</settings>

以上配置中,mirrorOf 元素的取值为 * ,表示匹配所有远程仓库,所有对于远程仓库的请求都会被拦截,并跳转到 url 元素指定的地址。

为了满足一些较为复杂的需求,Maven 还支持一些更为高级的配置。

  • *:匹配所有远程仓库。
  • external:*:匹配所有远程仓库,使用 localhost 和 file:// 协议的除外。即,匹配所有不在本机上的远程仓库。
  • repo1,repo2:匹配仓库 repo1 和 repo2,使用逗号分隔多个远程仓库。
  • *,!repo1:匹配所有远程仓库,repo1 除外,使用感叹号将仓库从匹配中排除。

需要注意的是,由于镜像仓库完全屏蔽了被镜像仓库,当镜像仓库不稳定或者停止服务时,Maven 也无法访问被镜像仓库,因而将无法下载构件。

3.7 Maven 私服

1、说明:

Maven 私服是一种特殊的远程仓库,它是架设在局域网内的仓库服务,用来代理位于外部的远程仓库(中央仓库、其他远程公共仓库)。

2、步骤:

建立了 Maven 私服后,当局域网内的用户需要某个构件时,会按照如下顺序进行请求和下载。

  1. 请求本地仓库,若本地仓库不存在所需构件,则跳转到第 2 步;
  2. 请求 Maven 私服,将所需构件下载到本地仓库,若私服中不存在所需构件,则跳转到第 3 步。
  3. 请求外部的远程仓库,将所需构件下载并缓存到 Maven 私服,若外部远程仓库不存在所需构件,则 Maven 直接报错。

此外,一些无法从外部仓库下载到的构件,也能从本地上传到私服供其他人使用。

下图中展示了 Maven 私服的用途。

image-20211011234452564

3、Maven 私服优势

Maven 私服具有以下 5 点优势:

节省外网带宽

大量对于外部远程仓库的重复请求,会消耗很大量的带宽,利用 Maven 私服代理外部仓库后,能够消除对外部仓库的大量重复请求,降低外网带宽压力。

下载速度更快

Maven 私服位于局域网内,从私服下载构建更快更稳定。

便于部署第三方构件

有些构件是无法从任何一个远程仓库中获得的(例如,某公司或组织内部的私有构件、Oracle 的 JDBC 驱动等),建立私服之后,就可以将这些构件部署到私服中,供内部 Maven 项目使用。

提高项目的稳定性,增强对项目的控制

如果不建立私服,那么 Maven 项目的构件就高度依赖外部的远程仓库,若外部网络不稳定,则项目的构建过程也会变得不稳定。
建立私服后,即使外部网络状况不佳甚至中断,只要私服中已经缓存了所需的构件,Maven 也能够正常运行。

此外,一些私服软件(如 Nexus)还提供了很多额外控制功能,例如,权限管理、RELEASE/SNAPSHOT 版本控制等,可以对仓库进行一些更加高级的控制。

降低中央仓库得负荷压力

由于私服会缓存中央仓库得构件,避免了很多对中央仓库的重复下载,降低了中央仓库的负荷。

4、Maven 私服搭建

能够帮助我们建立私服的软件被称为 Maven 仓库管理器(Repository Manager),主要有以下 3 种:

  • Apache Archiva
  • JFrog Artifactory
  • Sonatype Nexus

其中,Sonatype Nexus 是当前最流行,使用最广泛的 Maven 仓库管理器。您可以转到Nexus教程,学习 Maven 私服的搭建流程。

3.8 Maven 配置web项目

到目前为止,我们所接触的 Maven 项目的打包类型只有 JAR 和 POM ,但在现今的互联网时代,我们创建的大部分应用程序都是 Web 应用,在 Java 中 Web 应用的打包方式是 WAR。

本节我们将介绍如何使用 Maven 创建、构建、部署和运行 Web 应用程序。

1、创建 Web 应用

通过使用 Maven 的 maven-archetype-webapp 模板可以创建一个简单的 Web 应用。

例如,在命令行窗口执行以下命令,Maven 会为我们创建一个 JavaWeb 应用。

n archetype:generate -DgroupId=net.biancheng.www -DartifactId=mavenWeb -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false

执行结果如下。

[INFO] Scanning for projects...[INFO][INFO] ------------------< org.apache.maven:standalone-pom >-------------------[INFO] Building Maven Stub Project (No POM) 1[INFO] --------------------------------[ pom ]---------------------------------[INFO][INFO] >>> maven-archetype-plugin:3.2.0:generate (default-cli) > generate-sources @ standalone-pom >>>[INFO][INFO] <<< maven-archetype-plugin:3.2.0:generate (default-cli) < generate-sources @ standalone-pom <<<[INFO][INFO][INFO] --- maven-archetype-plugin:3.2.0:generate (default-cli) @ standalone-pom ---[INFO] Generating project in Batch mode[INFO] ----------------------------------------------------------------------------[INFO] Using following parameters for creating project from Old (1.x) Archetype: maven-archetype-webapp:1.0[INFO] ----------------------------------------------------------------------------[INFO] Parameter: basedir, Value: D:\MavenWeb[INFO] Parameter: package, Value: net.biancheng.www[INFO] Parameter: groupId, Value: net.biancheng.www[INFO] Parameter: artifactId, Value: mavenWeb[INFO] Parameter: packageName, Value: net.biancheng.www[INFO] Parameter: version, Value: 1.0-SNAPSHOT[INFO] project created from Old (1.x) Archetype in dir: D:\MavenWeb\mavenWeb[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time:  6.780 s[INFO] Finished at: 2021-03-29T10:23:18+08:00[INFO] ------------------------------------------------------------------------

命令执行完成后,Maven 为我们创建了一个名为 mavenWeb 的 JavaWeb 应用,其目录结构如图 1 所示。

image-20211012084353543

其中,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/maven-v4_0_0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>net.biancheng.www</groupId>    <artifactId>mavenWeb</artifactId>    <packaging>war</packaging>    <version>1.0-SNAPSHOT</version>    <name>mavenWeb Maven Webapp</name>    <url>http://maven.apache.org</url>    <dependencies>        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>            <version>3.8.1</version>            <scope>test</scope>        </dependency>    </dependencies>    <build>        <finalName>mavenWeb</finalName>    </build></project>

index.jsp 代码如下。

<html>    <body>        <h2>Hello World!</h2>    </body></html>

2、打包 Web 应用

Web 应用创建完成后,接下来我们将该应用进行打包成 war 文件,以便将其部署到服务器中。

打开命令行窗口,跳转到 mavenWeb 的目录,执行以下 mvn 命令,对该 Web 应用进行打包。

mvn clean package

结果如下。

[INFO] Scanning for projects...[INFO][INFO] ---------------------< net.biancheng.www:mavenWeb >---------------------[INFO] Building mavenWeb Maven Webapp 1.0-SNAPSHOT[INFO] --------------------------------[ war ]---------------------------------[INFO][INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ mavenWeb ---[INFO] Deleting D:\MavenWeb\mavenWeb\target[INFO][INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ mavenWeb ---[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent![INFO] Copying 0 resource[INFO][INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ mavenWeb ---[INFO] No sources to compile[INFO][INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ mavenWeb ---[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent![INFO] skip non existing resourceDirectory D:\MavenWeb\mavenWeb\src\test\resources[INFO][INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ mavenWeb ---[INFO] No sources to compile[INFO][INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ mavenWeb ---[INFO] No tests to run.[INFO][INFO] --- maven-war-plugin:2.2:war (default-war) @ mavenWeb ---[INFO] Packaging webapp[INFO] Assembling webapp [mavenWeb] in [D:\MavenWeb\mavenWeb\target\mavenWeb][INFO] Processing war project[INFO] Copying webapp resources [D:\MavenWeb\mavenWeb\src\main\webapp][INFO] Webapp assembled in [34 msecs][INFO] Building war: D:\MavenWeb\mavenWeb\target\mavenWeb.war[INFO] WEB-INF\web.xml already added, skipping[INFO] ------------------------------------------------------------------------[INFO] BUILD SUCCESS[INFO] ------------------------------------------------------------------------[INFO] Total time:  1.001 s[INFO] Finished at: 2021-03-29T12:37:37+08:00[INFO] ------------------------------------------------------------------------

打包完成后,进入 D:\MavenWeb\mavenWeb\target 目录,可以看到该应用打包生成的 war 文件,如图 2 所示。

image-20211012084516656

3、部署 Web 应用

将 mavenWeb 的 war 文件复制到 Tomcat 服务器的 webapp 目录中,然后重新启动 Tomcat 服务器。

Tomcat 启动完成后,在浏览器地址栏输入“http://localhost:8080/mavenWeb/index.jsp”,结果如图 3 所示。

image-20211012084542433

第三章 Maven和idea的集成

3.1 idea中集成maven

idea中有一个自带的maven。 我们要让idea使用自己安装的maven。

  1. 选择File- Settings

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X5py52Tl-1634806280184)(…/…/…/…/学习/Maven/资料/06-笔记/maven/images/image-20201016151034872.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WridDGwn-1634806280193)(…/…/…/…/学习/Maven/资料/06-笔记/maven/images/image-20201016151528678.png)]

设置项: -DarchetypeCatalog=internal

2) File - Other Settings

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m9rPnE3f-1634806280201)(…/…/…/…/学习/Maven/资料/06-笔记/maven/images/image-20201016151823967.png)]

同上的设置

3.2 创建基于maven的普通java项目

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sH8uygBA-1634806280204)(…/…/…/…/学习/Maven/资料/06-笔记/maven/images/image-20201016161028977.png)]

3.3 创建web项目

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-14hAKw0Z-1634806280208)(…/…/…/…/学习/Maven/资料/06-笔记/maven/images/image-20201016170153694.png)]

3.4 导入module到idea

  1. 在 IntelliJ IDEA 欢迎页面左侧选择 Projects,然后在右侧点击 Open 图标,如下图。

    image-20211012085259931

    或者在 IntelliJ IDEA 工作区上方的菜单栏中选择 File ,在下拉菜单选中 Open,如下图。

    image-20211012085322878
  2. 选择需要导入的 Maven 项目,如下图。

    image-20211012085347193
  3. 若该项目是第一次在 IDEA 中打开,IntelliJ IDEA 会对其进行分析。如果检测到多个配置(例如 Eclipse 和 Maven),则提示用户选择需要使用的配置,最后单击 OK 按钮,如下图。

    image-20211012085407605
  4. 进入安全提示对话框,这里我们直接选择 Trust Project 按钮,如下图。

    image-20211012085432475
  5. 返回 IDEA 工作区,可以看到项目已经导入,如下图。

    image-20211012085448586

3.5idea执行Maven命令

在工作区的最右侧,IntelliJ IDEA 为我们提供了一个十分实用的窗口:Maven 工具窗口,通过它我们几乎可以完成所有与 Maven 相关的操作。

image-20211012085554069

在 Maven 工具窗口中,我们可以通过以下 3 种方式中执行 Maven 命令:

1、使用 Run Anything 窗口

在 Maven 工具窗口的工具栏上,点击“m”按钮,或在 IntelliJ IDEA 中连续两次按下 Ctrl 键,即可打开 Run Anything 窗口,如图 2 所示。

image-20211012085648650

在 Run Anything 窗口输入或选择下方列表中 Maven 目标,回车即可执行,如图 3 所示。

image-20211012085704406

Maven 目标执行结果如图 4 所示。

image-20211012085719720

如果一个项目包含多个模块,且需要在特定的模块中执行 Maven 目标,则需要在 Run Anything 窗口右上角从“Project”列表中切换到所需的模块,然后再执行的 Maven 目标执行。

image-20211012085739488

2、使用 Maven 工具窗口的上下文菜单

在 Maven 工具窗口,点击项目名下面的 LifeCycle,如图 6 所示。

image-20211012085804093

右键单击 Maven 目标,在上下文菜单选择 Run ‘项目名 [Maven 目标]’(例如:Run ‘secondEclipse [clean]’),即可执行该目标,如图 7 所示。

image-20211012085823896

3、通过运行配置执行 Maven 目标

IntelliJ IDEA 还可以创建运行配置,来执行一个或多个 Maven 目标,步骤如下。

  1. 在 Maven 工具窗口,点击项目名下面的 LifeCycle。

  2. 按住 Ctrl 键同时选择一个或多个 Maven 目标,然后单击鼠标右键,在下拉菜单中选择 Create Run Configuration… 或者 Modify Run Configuration… ,如图 8 所示。

    image-20211012085905300
  3. 在创建运行配置窗口,我们可以为 Maven 目标指定 Maven 命令和参数等,设置完成后,点击 OK 按钮保存该运行配置,如图 9 所示。

    image-20211012090037845
  4. 配置完成后,在 Maven 工具窗口下自动生成了一个 Run Configurations 节点,再该节点下可以看到运行配置列表,如图 10 所示。

    image-20211012090024536
  5. 在运行配置列表中,双击目标,或右键点击该目标然从上下文菜单中选择 Run,即可运行该目标。

    image-20211012090010453

第四章 常用设置

1)讲的是properties它里面的配置

<properties><maven.compiler.source>1.8</maven.compiler.source> 源码编译 jdk 版本<maven.compiler.target>1.8</maven.compiler.target> 运行代码的 jdk 版本<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 项目构建使用的编码,避免中文乱码<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> 生成报告的编码</properties>
  1. 全局变量

在properties定义标签,这个标签就是一个变量, 标签的文本就是变量的值。

使用全局变量表示 多个依赖使用的版本号。

使用步骤:

1.在properties标签中,定义一个标签,指定版本的值

<properties>  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  <maven.compiler.source>1.8</maven.compiler.source>  <maven.compiler.target>1.8</maven.compiler.target>  <!--自定义变量-->  <spring.version>5.2.5.RELEASE</spring.version>  <junit.version>4.11</junit.version></properties>
  1. 使用全局变量, 语法 ${变量名}
<dependency>  <groupId>org.springframework</groupId>  <artifactId>spring-core</artifactId>  <version>${spring.version}</version></dependency><dependency>  <groupId>org.springframework</groupId>  <artifactId>spring-web</artifactId>  <version>${spring.version}</version></dependency>

3)使用资源插件

处理的配置文件的信息, maven默认处理配置文件

①:maven会把src/main/resources目录中的文件, 拷贝到target/classes目录下

②:maven只处理src/main/java目录中的 .java文件,把这些java文件编译为class,拷贝到 target/classes目录中。 不处理其他文件。

<build>  <!--资源插件      告诉maven把 src/main/java目录中的 指定扩展名的文件 拷贝到 target/classes目录中。  -->  <resources>    <resource>      <directory>src/main/java</directory><!--所在的目录-->      <includes>      <!--包括目录下的.properties,.xml 文件都会扫描到-->        <include>**/*.properties</include>        <include>**/*.xml</include>      </includes>        <!--  filtering 选项 false 不启用过滤器, *.property 已经起到过        滤的作用了 -->      <filtering>false</filtering>    </resource>  </resources></build>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值