文章目录
- 1. 重新认识pom文件
- 2. 重要标签详解
-
- 2.1 dependencyManagement标签
- 2.2 build标签
-
- 2.2.1 约定的目录结构
- 2.2.2 备用插件管理
- 2.2.3 生命周期插件
-
- 2.3.3.1 坐标部分
- 2.3.3.2 执行部分
- 3. 典型应用
-
- 3.1 指定 JDK 版本
-
- 3.1.1 提出问题
- 3.1.2 暂时取消 settings.xml 配置
- 3.1.3 编写源文件代码
- 3.1.4 配置构建过程
- 3.1.5 两种配置方式比较
- 3.1.6 补充说明
-
- configuration标签中source 标签含义
- target 标签含义
- 3.2 SpringBoot 定制化打包
-
- 3.2.1 需求
- 3.2.2 示例代码
- 3.2.3 插件的七个目标
- 3.3 Mybatis 逆向工程
- 3.4 小结
- 附录:完整 build 标签
1. 重新认识pom文件
我们都知道,Maven
是一款项目构建管理和依赖管理的工具,但事实上这只是 Maven
的一部分功能,Maven
本身的产品定位是一款项目管理工具。
下面是 spring-boot-starter
的 POM
文件,可以看到:除了熟悉的GAV
坐标标签、dependencies
标签,还有 description
、url
、organization
、licenses
、developers
、scm
、issueManagement
等这些描述项目信息的标签。
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.5.6</version>
<name>spring-boot-starter</name>
<description>Core starter, including auto-configuration support, logging and YAML</description>
<url>https://spring.io/projects/spring-boot</url>
<organization>
<name>Pivotal Software, Inc.</name>
<url>https://spring.io</url>
</organization>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>
<developers>
<developer>
<name>Pivotal</name>
<email>info@pivotal.io</email>
<organization>Pivotal Software, Inc.</organization>
<organizationUrl>https://www.spring.io</organizationUrl>
</developer>
</developers>
<scm>
<connection>scm:git:git://github.com/spring-projects/spring-boot.git</connection>
<developerConnection>scm:git:ssh://git@github.com/spring-projects/spring-boot.git</developerConnection>
<url>https://github.com/spring-projects/spring-boot</url>
</scm>
<issueManagement>
<system>GitHub</system>
<url>https://github.com/spring-projects/spring-boot/issues</url>
</issueManagement>
<dependencies>
<dependency>
……
</dependency>
</dependencies>
</project>
从项目管理的角度来看,Maven
提供了如下这些功能:
- 项目对象模型(
POM
):将整个项目本身抽象、封装为应用程序中的一个对象,以便于管理和操作。 - 全局性构建逻辑重用:
Maven
对整个构建过程进行封装之后,程序员只需要指定配置信息即可完成构建。 - 构件的标准集合:在
Maven
提供的标准框架体系内,所有的构件都可以按照统一的规范生成和使用。 - 构件关系定义:
Maven
定义了构件之间的三种基本关系,让大型应用系统可以使用Maven
来进行管理- 继承关系:通过从上到下的继承关系,将各个子构件中的重复信息提取到父构件中统一管理
- 聚合关系:将多个构件聚合为一个整体,便于统一操作
- 依赖关系:
Maven
定义了依赖的范围、依赖的传递、依赖的排除、版本仲裁机制等一系列规范和标准,让大型项目可以有序容纳数百甚至更多依赖
- 插件目标系统:
Maven
核心程序定义抽象的生命周期,然后将插件的目标绑定到生命周期中的特定阶段,实现了标准和具体实现解耦合,让Maven
程序极具扩展性 - 项目描述信息的维护:我们不仅可以在
POM
中声明项目描述信息,更可以将整个项目相关信息收集起来生成 HTML 页面组成的一个可以直接访问的站点。这些项目描述信息包括:- 公司或组织信息
- 项目许可证
- 开发成员信息
issue
管理信息SCM
信息
2. 重要标签详解
2.1 dependencyManagement标签
该标签用来在根pom
中管理jar
包版本,如果后面的jar
包没有申明版本,会以这里面的版本为主,使用该标签并不会引入jar
包,一般是在父级pom
文件申明,方便管理jar
包版本
2.2 build标签
在实际使用 Maven
的过程中,会发现 build
标签有时候有,有时候没,这是怎么回事呢?其实通过有效 POM
我们能够看到,build
标签的相关配置其实一直都在,只是在我们需要定制构建过程的时候才会通过配置 build
标签覆盖默认值或补充配置。这一点我们可以通过打印有效 POM
来看到。
完整 build 标签示例在文章末尾,从中能够看到,build
标签的子标签大致包含三个主体部分:
2.2.1 约定的目录结构
参考附录中的如下部分:
<sourceDirectory>D:\idea\maven-test\src\main\java</sourceDirectory>
<scriptSourceDirectory>D:\idea\maven-test\src\main\scripts</scriptSourceDirectory>
<testSourceDirectory>D:\idea\maven-test\src\test\java</testSourceDirectory>
<outputDirectory>D:\idea\maven-test\target\classes</outputDirectory>
<testOutputDirectory>D:\idea\maven-test\target\test-classes</testOutputDirectory>
<resources>
<resource>
<directory>D:\idea\maven-test\src\main\resources</directory>
</resource>
</resources>
<testResources>
<testResource>
<directory>D:\idea\maven-test\src\test\resources</directory>
</testResource>
</testResources>
<directory>D:\idea\maven-test\target</directory>
能看到各个目录的作用如下:
目录名 | 作用 |
---|---|
sourceDirectory |
主体源程序存放目录 |
scriptSourceDirectory |
脚本源程序存放目录 |
testSourceDirectory |
测试源程序存放目录 |
outputDirectory |
主体源程序编译结果输出目录 |
testOutputDirectory |
测试源程序编译结果输出目录 |
resources |
主体资源文件存放目录 |
testResources |
测试资源文件存放目录 |
directory |
构建结果输出目录 |
2.2.2 备用插件管理
pluginManagement
标签存放着几个极少用到的插件:
maven-antrun-plugin
maven-assembly-plugin
maven-dependency-plugin
maven-release-plugin
通过 pluginManagement
标签管理起来的插件就像 dependencyManagement
一样,子工程使用时可以省略版本号,起到在父工程中统一管理版本的效果,看下面例子:
- 被
spring-boot-dependencies
管理的插件信息:
<build>
<pluginManagement>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.6.2</version>
</plugin>
</pluginManagement>
</build>
- 子工程使用的插件信息:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
2.2.3 生命周期插件
plugins
标签存放的是默认生命周期中实际会用到的插件,这些插件应该都不陌生,所以抛开插件本身不谈,来看看 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>
2.3.3.1 坐标部分
artifactId
和 version
标签定义了插件的坐标,作为 Maven
的自带插件这里省略了 groupId
2.3.3.2 执行部分
executions
标签内可以配置多个 execution
标签,execution
标签内:
id
:指定唯一标识phase
:关联的生命周期阶段goals/goal
:关联指定生命周期的目标- goals 标签中可以配置多个 goal 标签,表示一个生命周期环节可以对应当前插件的多个目标。
phase元素代表的是绑定的生命周期的阶段
goals元素代表插件的目标,插件是前面artifactId中定义好的,goals相当于该插件中的一个功能,该功能将在phase绑定的生命周期阶段执行
另外,插件目标的执行过程可以进行配置,例如 maven-site-plugin
插件的 site
目标:
<execution>
<id>default-site</id>
<phase>site</phase>
<goals>
<goal>site</goal>
</goals>
<configuration>
<outputDirectory>D:\idea\maven-test\target\site</outputDirectory>
<reportPlugins>
<reportPlugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
</reportPlugin>
</reportPlugins>
</configuration>
</execution>
configuration
标签内进行配置时使用的标签是插件本身定义的。
结论:每个插件能够做哪些设置都是各个插件自己规定的。
3. 典型应用
3.1 指定 JDK 版本
3.1.1 提出问题
可以在Maven
的配置文件中 settings.xml
中配置了 JDK
版本,那么将来把 Maven
工程部署都服务器上,脱离了settings.xml
配置,如何保证程序正常运行呢?思路就是直接把 JDK
版本信息告诉负责编译操作的 maven-compiler-plugin
插件,让它在构建过程中,按照指定的信息工作
3.1.2 暂时取消 settings.xml 配置
为了测试对maven-compiler-plugin
插件进行配置的效果,暂时取消配置文件settings.xml
中的 profile
配置。
<!-- 配置Maven工程的默认JDK版本 -->
<!-- <profile>
<id>jdk-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile> -->
3.1.3 编写源文件代码
很明显这里用到了 Lambda
表达式,这是 JDK 1.8
才支持的语法
package com.scorpios.maven;
public class Hello {
public void hello() {
new Thread(()->{
System.out.println("thread ...");
}).start();
}
}
3.1.4 配置构建过程
<!-- build 标签:意思是告诉 Maven,你的构建行为,我要开始定制了! -->
<build>
<!-- plugins 标签:Maven 你给我听好了,你给我构建的时候要用到这些插件! -->
<plugins>
<!-- plugin 标签:这是我要指定的一个具体的插件 -->
<plugin>
<!-- 插件的坐标。此处引用的 maven-compiler-plugin 插件不是第三方的,是一个 Maven 自带的插件。 -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<!-- configuration 标签:配置 maven-compiler-plugin 插件 -->
<configuration>
<!-- 具体配置信息会因为插件不同、需求不同而有所差异 -->
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
3.1.5 两种配置方式比较
settings.xml
中配置:仅在本地生效,如果脱离当前settings.xml
能够覆盖的范围,则无法生效- 在当前
Maven
工程pom.xml
中配置:无论在哪个环境执行编译等构建操作都有效
3.1.6 补充说明
configuration标签中source 标签含义
调用 Java
编译器命令时传入的-source
参数。那对编译器来说,-source
参数是啥意思呢?
『提供与指定发行版的源兼容性』这句话理解是:
- 我们写代码是按 JDK 1.8 写的——这就是『源兼容性』里的『源』。
- 指定发行版就是我们指定的 JDK 1.8。
这个功能还可以通过在 properties
标签中配置 maven.compiler.source
属性来实现。所以也经常会看到类似这样的配置:
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
target 标签含义
调用 Java
编译器命令时传入的-target
参数。那对编译器来说,-target
参数是啥意思呢?
『生成特定 VM
版本的类文件』这句话理解是:
VM
指JVM
- 类文件指
*.class
字节码文件 - 整体意思就是源文件编译后,生成的
*.class
字节码文件要符合指定的JVM
版本
3.2 SpringBoot 定制化打包
3.2.1 需求
很显然 spring-boot-maven-plugin
并不是 Maven
自带的插件,而是 SpringBoot
提供的,用来改变 Maven
默认的构建行为。具体来说是改变打包的行为。默认情况下 Maven
调用 maven-jar-plugin
插件的 jar 目标,生成普通的 jar 包。
普通 jar
包没法使用java -jar xxx.jar
这样的命令来启动、运行,但是 SpringBoot
的设计理念就是每一个微服务导出为一个 jar
包,这个 jar
包可以使用 java -jar xxx.jar
这样的命令直接启动运行。
这样一来,打包的方式肯定要进行调整。所以 SpringBoot
提供了 spring-boot-maven-plugin
这个插件来定制打包行为。
3.2.2 示例代码
所有的一切已经都被 SpringBoot
封装好了,所以配置非常简单,提供插件坐标即可。
<!-- build 标签:用来配置对构建过程的定制 -->
<build>
<!-- plugins 标签:定制化构建过程中所使用到的插件 -->
<plugins>
<!-- plugin 标签:一个具体插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.5.5</version>
</plugin>
</plugins>
</build>
3.2.3 插件的七个目标
目标名称 | 作用 |
---|---|
spring-boot:build-image | 使用构建包将应用程序打包到OCI映像中 |
spring-boot:build-info | 生成Actuator使用的构建信息文件build-info.properties |
spring-boot:help | 配置pom.xml文件 |
spring-boot:repackage | 默认goal。在mvn package之后,再次打包可执行的jar/war,同时保留mvn package生成的jar/war为.origin |
spring-boot:run | 运行Spring Boot应用 |
spring-boot:start | 在mvn integration-test阶段,进行Spring Boot应用生命周期的管理 |
spring-boot:stop | 在mvn integration-test阶段,进行Spring Boot应用生命周期的管理 |
3.3 Mybatis 逆向工程
使用 Mybatis
的逆向工程需要使用如下配置,MBG
插件的特点是需要提供插件所需的依赖:
<!-- 控制 Maven 在构建过程中相关配置 -->
<build>
<!-- 构建过程中用到的插件 -->
<plugins>
<!-- 具体插件,逆向工程的操作是以构建过程中插件形式出现的 -->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.0</version>
<!-- 插件的依赖 -->
<dependencies>
<!-- 逆向工程的核心依赖 -->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.2</version>
</dependency>
<!-- 数据库连接池 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.2</version>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.8</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
3.4 小结
通常需要用到 build
标签的时候底层都会封装好,需要自己配置的地方不多。即使有些地方需要自己配置,也不会真的需要自己去写,把现成的案例复制过来就行。
附录:完整 build 标签
<build>
<!--约定的目录结构-->
<sourceDirectory>D:\idea\maven-test\src\main\java</sourceDirectory>
<scriptSourceDirectory>D:\idea\maven-test\src\main\scripts</scriptSourceDirectory>
<testSourceDirectory>D:\idea\maven-test\src\test\java</testSourceDirectory>
<outputDirectory>D:\idea\maven-test\target\classes</outputDirectory>
<testOutputDirectory>D:\idea\maven-test\target\test-classes</testOutputDirectory>
<resources>
<resource>
<directory>D:\idea\maven-test\src\main\resources</directory>
</resource>
</resources>
<testResources>
<testResource>
<directory>D:\idea\maven-test\src\test\resources</directory>
</testResource>
</testResources>
<directory>D:\idea\maven-test\target</directory>
<finalName>maven-test-1.0-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:\idea\maven-test\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:\idea\maven-test\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:\idea\maven-test\target\site</outputDirectory>
<reportPlugins>
<reportPlugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
</reportPlugin>
</reportPlugins>
</configuration>
</plugin>
</plugins>
</build>