Maven 配置你的常用插件
本篇主要内容为你常用的插件的配置,帮助你了解你使用的插件到底做了什么
实际上你在工作中只需要理解 compile 标签中的 source 和 target 即可
clean
当你使用 mvn clean
时实际上就是在调用这个插件 默认情况下会帮你删除 target
文件夹
如果你需要删除额外的文件/文件夹则可以进行额外的配置
<build>
[...]
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<filesets>
<fileset>
<directory>some/relative/path</directory>
<includes>
<include>**/*.tmp</include>
<include>**/*.log</include>
</includes>
<excludes>
<exclude>**/important.log</exclude>
<exclude>**/another-important.log</exclude>
</excludes>
<followSymlinks>false</followSymlinks>
</fileset>
</filesets>
</configuration>
</plugin>
</plugins>
[...]
</build>
其实 fileset 标签中的路径是相对路径 其等价于
<directory>${basedir}/some/relative/path</directory>
如果你想要跳过 clean 也是可以的
<pluign>
<artifactId>...</artifactId>
<version>..</version>
<configuration>
<skip>true</skip>
</configuration>
</pluign>
或者在执行命令的时候
mvn clean -Dmaven.clean.skip=true
compile
这个插件是个非常重要的插件,用来编译你的 java 代码
编译器插件的目标与构建生命周期中各自的阶段有关。因此,要编译源代码,只需告诉 maven 要执行哪个生命周期。
mvn compile
如果指定要编译 test 部分的代码你需要这样指定
mvn test-compile
使用不同的 jdk 进行编译
Maven 默认使用的是 JAVA_HOME 的环境变量来找到 Java 环境进行编译,即找到 JAVA_HOME\bin\javac 来进行编译
有些时候本地使用的 jdk 和实际需要的 jdk 是不一样的,比如说你本地环境是 jdk17,然而你目前正在尝鲜 jdk19ea,而又不想切换本地环境,那就可以在编译的时候指定这个 jdk
这里你需要指定 fork 为 true,然后指定一下 executable 为你想要的 jdk
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<verbose>true</verbose>
<fork>true</fork>
<executable>${loom.path}/bin/javac</executable>
</configuration>
</plugin>
指定使用的 jdk 版本
如果你本地环境是 17,而线上是 11,而且你使用的 api 和语法都是降级到 11 也可以兼容的,那么你就可以设置 jdk 版本指定编译出来的版本。即对应 javac 的 -source
和 -target
参数
方法一
<project>
[...]
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
[...]
</project>
方法二
<project>
[...]
<build>
[...]
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
</plugins>
[...]
</build>
[...]
</project>
指定编译器参数
javac 实际上是支持很多参数的
比如说最常用的 -paramters
参数用于将方法参数名编译进去,还有打开某些模块,开启预览功能等
你就可以这样指定
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
<arg>--add-exports</arg>
<arg>java.base/jdk.internal.vm=mainModule</arg>
<arg>--enable-preview</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
surefire (test 阶段使用的)
这一部分最有用的应该还是如何跳过 test
跳过测试
方法一
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>...</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
[...]
</project>
方法二
mvn install -DskipTests
方法三
mvn install -Dmaven.test.skip=true
注意这个方法三连测试类都不会编译,而其他两种则会编译。
shade
这个插件其实非常强大 但是往往我们只使用他的打 fatjar 的功能,把全部依赖都打到一个 jar 下面
没有这个插件直接 mvn package
只能把你的 src 文件夹下面的代码和 pom.xml 打包到一个 jar 下面
而 shade 这个插件会在 package 阶段调用,帮你把这些依赖一起打进去
可执行的 fat-jar/Uber-jar
作为可执行的 jar 应该是包含全部依赖且包含一个 main 函数
你只要这样配置就行了
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>${main.class}</Main-Class>
<key>value</key>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
实际上 manifestEntries 标签的子内容就是打包到 jar 包下面 META-INF/MANIFEST.MF
文件的内容
标签名就是 key 标签内容就是 value
过滤不需要的文件
下面的 POM 代码片段显示了如何控制 uber JAR 中应该包含/排除哪些项目依赖项:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<excludes>
<exclude>classworlds:classworlds</exclude>
<exclude>junit:junit</exclude>
<exclude>jmock:*</exclude>
<exclude>*:xml-apis</exclude>
<exclude>org.apache.maven:lib:tests</exclude>
<exclude>log4j:log4j:jar:</exclude>
</excludes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
shade (重命名)
如果 uber JAR 被重用为其他项目的依赖项,直接将依赖项中的类包含在 uber JAR 中可能会由于类路径上的重复类而导致类加载冲突。为了解决这个问题,可以重命名其中包含的类,以便创建私有的字节码副本。
这个才是 shade 的本意,举个例子 spring 的 cglib 依赖就是从原依赖改名为其他的
当然了 spring-core 维护用的是 gradle 但是其实用的也是这个插件
然后我们直接来看配置
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<relocations>
<relocation>
<pattern>org.codehaus.plexus.util</pattern>
<shadedPattern>org.shaded.plexus.util</shadedPattern>
<excludes>
<exclude>org.codehaus.plexus.util.xml.Xpp3Dom</exclude>
<exclude>org.codehaus.plexus.util.xml.pull.*</exclude>
</excludes>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
一目了然
SpringBoot 插件
我们在 springboot 开发中会发现其实很多情况下我们只需要它自己带的一个 SpringBoot 插件,这个插件实际上是个复合插件(比如 shade 等),通过配置这个插件就可以做到很多事情
首先你的项目肯定是继承于 spring-boot-starter-parent
的,所以它默认有这些特性
- 默认编译的目标版本是 1.8
- 默认 UTF-8 作为文件编码
- 编译参数带有
-paramters
- 过滤了一些合理的资源
- 合理的插件配置
从命令行覆盖配置
例如,可以在运行应用程序时调整配置文件以选择启用哪个文件,如下所示:
mvn spring-boot:run -Dspring-boot.run.profiles=dev,local
打包为可执行的 jar 包
你只需要 mvn package
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
如果你的项目继承的是 spring-boot-starter-parent
,那么这样的执行已经预先配置了一个 repackage
execution ID,因此只需要添加插件定义就行了。
它同时会产生以一个同名但是以 .original
结尾的文件,这个就是一个只包含 src 代码的 jar 包
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论