我们都知道,Maven
是一款项目构建管理和依赖管理的工具,但事实上这只是 Maven
的一部分功能,Maven
本身的产品定位是一款项目管理工具。
下面是 spring-boot-starter
的 POM
文件,可以看到:除了熟悉的GAV
坐标标签、dependencies
标签,还有 description
、url
、organization
、licenses
、developers
、scm
、issueManagement
等这些描述项目信息的标签。
<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.0modelVersion>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starterartifactId>
<version>2.5.6version>
<name>spring-boot-startername>
<description>Core starter, including auto-configuration support, logging and YAMLdescription>
<url>https://spring.io/projects/spring-booturl>
<organization>
<name>Pivotal Software, Inc.name>
<url>https://spring.iourl>
organization>
<licenses>
<license>
<name>Apache License, Version 2.0name>
<url>https://www.apache.org/licenses/LICENSE-2.0url>
license>
licenses>
<developers>
<developer>
<name>Pivotalname>
<email>[email protected]email>
<organization>Pivotal Software, Inc.organization>
<organizationUrl>https://www.spring.ioorganizationUrl>
developer>
developers>
<scm>
<connection>scm:git:git://github.com/spring-projects/spring-boot.gitconnection>
<developerConnection>scm:git:ssh://[email protected]/spring-projects/spring-boot.gitdeveloperConnection>
<url>https://github.com/spring-projects/spring-booturl>
scm>
<issueManagement>
<system>GitHubsystem>
<url>https://github.com/spring-projects/spring-boot/issuesurl>
issueManagement>
<dependencies>
<dependency>
……
dependency>
dependencies>
project>
从项目管理的角度来看,Maven
提供了如下这些功能:
POM
):将整个项目本身抽象、封装为应用程序中的一个对象,以便于管理和操作。Maven
对整个构建过程进行封装之后,程序员只需要指定配置信息即可完成构建。Maven
提供的标准框架体系内,所有的构件都可以按照统一的规范生成和使用。Maven
定义了构件之间的三种基本关系,让大型应用系统可以使用 Maven
来进行管理
Maven
定义了依赖的范围、依赖的传递、依赖的排除、版本仲裁机制等一系列规范和标准,让大型项目可以有序容纳数百甚至更多依赖Maven
核心程序定义抽象的生命周期,然后将插件的目标绑定到生命周期中的特定阶段,实现了标准和具体实现解耦合,让 Maven
程序极具扩展性POM
中声明项目描述信息,更可以将整个项目相关信息收集起来生成 HTML 页面组成的一个可以直接访问的站点。这些项目描述信息包括:
issue
管理信息SCM
信息该标签用来在根pom
中管理jar
包版本,如果后面的jar
包没有申明版本,会以这里面的版本为主,使用该标签并不会引入jar
包,一般是在父级pom
文件申明,方便管理jar
包版本
在实际使用 Maven
的过程中,会发现 build
标签有时候有,有时候没,这是怎么回事呢?其实通过有效 POM
我们能够看到,build
标签的相关配置其实一直都在,只是在我们需要定制构建过程的时候才会通过配置 build
标签覆盖默认值或补充配置。这一点我们可以通过打印有效 POM
来看到。
完整 build 标签示例在文章末尾,从中能够看到,build
标签的子标签大致包含三个主体部分:
参考附录中的如下部分:
<sourceDirectory>D:\idea\maven-test\src\main\javasourceDirectory>
<scriptSourceDirectory>D:\idea\maven-test\src\main\scriptsscriptSourceDirectory>
<testSourceDirectory>D:\idea\maven-test\src\test\javatestSourceDirectory>
<outputDirectory>D:\idea\maven-test\target\classesoutputDirectory>
<testOutputDirectory>D:\idea\maven-test\target\test-classestestOutputDirectory>
<resources>
<resource>
<directory>D:\idea\maven-test\src\main\resourcesdirectory>
resource>
resources>
<testResources>
<testResource>
<directory>D:\idea\maven-test\src\test\resourcesdirectory>
testResource>
testResources>
<directory>D:\idea\maven-test\targetdirectory>
能看到各个目录的作用如下:
目录名 | 作用 |
---|---|
sourceDirectory |
主体源程序存放目录 |
scriptSourceDirectory |
脚本源程序存放目录 |
testSourceDirectory |
测试源程序存放目录 |
outputDirectory |
主体源程序编译结果输出目录 |
testOutputDirectory |
测试源程序编译结果输出目录 |
resources |
主体资源文件存放目录 |
testResources |
测试资源文件存放目录 |
directory |
构建结果输出目录 |
pluginManagement
标签存放着几个极少用到的插件:
maven-antrun-plugin
maven-assembly-plugin
maven-dependency-plugin
maven-release-plugin
通过 pluginManagement
标签管理起来的插件就像 dependencyManagement
一样,子工程使用时可以省略版本号,起到在父工程中统一管理版本的效果,看下面例子:
spring-boot-dependencies
管理的插件信息:<build>
<pluginManagement>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<version>2.6.2version>
plugin>
pluginManagement>
build>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
plugins
标签存放的是默认生命周期中实际会用到的插件,这些插件应该都不陌生,所以抛开插件本身不谈,来看看 plugin
标签的结构:
<plugin>
<artifactId>maven-compiler-pluginartifactId>
<version>3.1version>
<executions>
<execution>
<id>default-compileid>
<phase>compilephase>
<goals>
<goal>compilegoal>
goals>
execution>
<execution>
<id>default-testCompileid>
<phase>test-compilephase>
<goals>
<goal>testCompilegoal>
goals>
execution>
executions>
plugin>
artifactId
和 version
标签定义了插件的坐标,作为 Maven
的自带插件这里省略了 groupId
executions
标签内可以配置多个 execution
标签,execution
标签内:
id
:指定唯一标识phase
:关联的生命周期阶段goals/goal
:关联指定生命周期的目标
phase元素代表的是绑定的生命周期的阶段
goals元素代表插件的目标,插件是前面artifactId中定义好的,goals相当于该插件中的一个功能,该功能将在phase绑定的生命周期阶段执行
另外,插件目标的执行过程可以进行配置,例如 maven-site-plugin
插件的 site
目标:
<execution>
<id>default-siteid>
<phase>sitephase>
<goals>
<goal>sitegoal>
goals>
<configuration>
<outputDirectory>D:\idea\maven-test\target\siteoutputDirectory>
<reportPlugins>
<reportPlugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-project-info-reports-pluginartifactId>
reportPlugin>
reportPlugins>
configuration>
execution>
configuration
标签内进行配置时使用的标签是插件本身定义的。
结论:每个插件能够做哪些设置都是各个插件自己规定的。
可以在Maven
的配置文件中 settings.xml
中配置了 JDK
版本,那么将来把 Maven
工程部署都服务器上,脱离了settings.xml
配置,如何保证程序正常运行呢?思路就是直接把 JDK
版本信息告诉负责编译操作的 maven-compiler-plugin
插件,让它在构建过程中,按照指定的信息工作
为了测试对maven-compiler-plugin
插件进行配置的效果,暂时取消配置文件settings.xml
中的 profile
配置。
很明显这里用到了 Lambda
表达式,这是 JDK 1.8
才支持的语法
package com.scorpios.maven;
public class Hello {
public void hello() {
new Thread(()->{
System.out.println("thread ...");
}).start();
}
}
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>3.1version>
<configuration>
<source>1.8source>
<target>1.8target>
<encoding>UTF-8encoding>
configuration>
plugin>
plugins>
build>
settings.xml
中配置:仅在本地生效,如果脱离当前 settings.xml
能够覆盖的范围,则无法生效Maven
工程 pom.xml
中配置:无论在哪个环境执行编译等构建操作都有效调用 Java
编译器命令时传入的-source
参数。那对编译器来说,-source
参数是啥意思呢?
『提供与指定发行版的源兼容性』这句话理解是:
这个功能还可以通过在 properties
标签中配置 maven.compiler.source
属性来实现。所以也经常会看到类似这样的配置:
<properties>
<maven.compiler.source>1.8maven.compiler.source>
<maven.compiler.target>1.8maven.compiler.target>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
properties>
调用 Java
编译器命令时传入的-target
参数。那对编译器来说,-target
参数是啥意思呢?
『生成特定 VM
版本的类文件』这句话理解是:
VM
指 JVM
*.class
字节码文件 *.class
字节码文件要符合指定的 JVM
版本很显然 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
这个插件来定制打包行为。
所有的一切已经都被 SpringBoot
封装好了,所以配置非常简单,提供插件坐标即可。
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<version>2.5.5version>
plugin>
plugins>
build>
目标名称 | 作用 |
---|---|
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应用生命周期的管理 |
使用 Mybatis
的逆向工程需要使用如下配置,MBG
插件的特点是需要提供插件所需的依赖:
<build>
<plugins>
<plugin>
<groupId>org.mybatis.generatorgroupId>
<artifactId>mybatis-generator-maven-pluginartifactId>
<version>1.3.0version>
<dependencies>
<dependency>
<groupId>org.mybatis.generatorgroupId>
<artifactId>mybatis-generator-coreartifactId>
<version>1.3.2version>
dependency>
<dependency>
<groupId>com.mchangegroupId>
<artifactId>c3p0artifactId>
<version>0.9.2version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.8version>
dependency>
dependencies>
plugin>
plugins>
build>
通常需要用到 build
标签的时候底层都会封装好,需要自己配置的地方不多。即使有些地方需要自己配置,也不会真的需要自己去写,把现成的案例复制过来就行。
<build>
<sourceDirectory>D:\idea\maven-test\src\main\javasourceDirectory>
<scriptSourceDirectory>D:\idea\maven-test\src\main\scriptsscriptSourceDirectory>
<testSourceDirectory>D:\idea\maven-test\src\test\javatestSourceDirectory>
<outputDirectory>D:\idea\maven-test\target\classesoutputDirectory>
<testOutputDirectory>D:\idea\maven-test\target\test-classestestOutputDirectory>
<resources>
<resource>
<directory>D:\idea\maven-test\src\main\resourcesdirectory>
resource>
resources>
<testResources>
<testResource>
<directory>D:\idea\maven-test\src\test\resourcesdirectory>
testResource>
testResources>
<directory>D:\idea\maven-test\targetdirectory>
<finalName>maven-test-1.0-SNAPSHOTfinalName>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-antrun-pluginartifactId>
<version>1.3version>
plugin>
<plugin>
<artifactId>maven-assembly-pluginartifactId>
<version>2.2-beta-5version>
plugin>
<plugin>
<artifactId>maven-dependency-pluginartifactId>
<version>2.8version>
plugin>
<plugin>
<artifactId>maven-release-pluginartifactId>
<version>2.5.3version>
plugin>
plugins>
pluginManagement>
<plugins>
<plugin>
<artifactId>maven-clean-pluginartifactId>
<version>2.5version>
<executions>
<execution>
<id>default-cleanid>
<phase>cleanphase>
<goals>
<goal>cleangoal>
goals>
execution>
executions>
plugin>
<plugin>
<artifactId>maven-resources-pluginartifactId>
<version>2.6version>
<executions>
<execution>
<id>default-testResourcesid>
<phase>process-test-resourcesphase>
<goals>
<goal>testResourcesgoal>
goals>
execution>
<execution>
<id>default-resourcesid>
<phase>process-resourcesphase>
<goals>
<goal>resourcesgoal>
goals>
execution>
executions>
plugin>
<plugin>
<artifactId>maven-jar-pluginartifactId>
<version>2.4version>
<executions>
<execution>
<id>default-jarid>
<phase>packagephase>
<goals>
<goal>jargoal>
goals>
execution>
executions>
plugin>
<plugin>
<artifactId>maven-compiler-pluginartifactId>
<version>3.1version>
<executions>
<execution>
<id>default-compileid>
<phase>compilephase>
<goals>
<goal>compilegoal>
goals>
execution>
<execution>
<id>default-testCompileid>
<phase>test-compilephase>
<goals>
<goal>testCompilegoal>
goals>
execution>
executions>
plugin>
<plugin>
<artifactId>maven-surefire-pluginartifactId>
<version>2.12.4version>
<executions>
<execution>
<id>default-testid>
<phase>testphase>
<goals>
<goal>testgoal>
goals>
execution>
executions>
plugin>
<plugin>
<artifactId>maven-install-pluginartifactId>
<version>2.4version>
<executions>
<execution>
<id>default-installid>
<phase>installphase>
<goals>
<goal>installgoal>
goals>
execution>
executions>
plugin>
<plugin>
<artifactId>maven-deploy-pluginartifactId>
<version>2.7version>
<executions>
<execution>
<id>default-deployid>
<phase>deployphase>
<goals>
<goal>deploygoal>
goals>
execution>
executions>
plugin>
<plugin>
<artifactId>maven-site-pluginartifactId>
<version>3.3version>
<executions>
<execution>
<id>default-siteid>
<phase>sitephase>
<goals>
<goal>sitegoal>
goals>
<configuration>
<outputDirectory>D:\idea\maven-test\target\siteoutputDirectory>
<reportPlugins>
<reportPlugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-project-info-reports-pluginartifactId>
reportPlugin>
reportPlugins>
configuration>
execution>
<execution>
<id>default-deployid>
<phase>site-deployphase>
<goals>
<goal>deploygoal>
goals>
<configuration>
<outputDirectory>D:\idea\maven-test\target\siteoutputDirectory>
<reportPlugins>
<reportPlugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-project-info-reports-pluginartifactId>
reportPlugin>
reportPlugins>
configuration>
execution>
executions>
<configuration>
<outputDirectory>D:\idea\maven-test\target\siteoutputDirectory>
<reportPlugins>
<reportPlugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-project-info-reports-pluginartifactId>
reportPlugin>
reportPlugins>
configuration>
plugin>
plugins>
build>