本文主要介绍了以下插件:
-
maven-compiler-plugin:编绎阶段指定jdk版本。
-
maven-surefire-plugin:用于测试阶段的插件
-
maven-failsafe-plugin:用作集成测试的配置。
-
maven-checkstyle-plugin:可以帮助开发检测代码中不合规范的地方。
-
build-helper-maven-plugin:支持多个source/test/resource。
-
spring-boot-maven-plugin:可以帮助项目打包成一个fat jar。
-
jacoco-maven-plugin:生成单元测试覆盖率报告。
-
sonar-maven-plugin:使用该插件执行sonar扫描。
1. maven-compiler-plugin
- 官网:maven.apache.org/plugins/mav…
- baeldung示例:www.baeldung.com/maven-compi…
这个插件会自动绑定到以下生命周期:
compile: compile main source filestestCompile: compile test source files
既然我们不主动声明,在使用命令mvn compile也会执行该插件,那么,在什么样的情况下,需要我们显式的声明该插件呢?
1.1 在编绎阶段指定JDK version
比如我们需要在编绎阶段使用不同的jdk的时候,可以显示的声明该插件:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
当然,我们也可以不用显示声明插件,而是使用properties来重置上述的source以及target中的值(这种方式更为常见):
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
注:jdk9以上,不能用1.9,而是要使用9,11,17这样的格式。
1.2 使用MapStruct的时候,在插件中配置
- MapStruct官网:mapstruct.org/
- baeldung示例:www.baeldung.com/mapstruct
MapStruct是Java的对象转换工具,可以通过依赖引入:
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.2.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.2.Final</version>
</dependency>
但这样的依赖有个缺陷,就是无法和Lombok一起工作,如果POJO类被Lombok的@Data修饰,而不是使用Getter/Setter,那么MapStruct在自动生成converter类的时候,会有问题。
如何解决?
可以在maven-compiler-plugin插件中配置annotationProcessorPaths。通过这样的方式,就可以解决MapStruct和Lombok无法一起使用的问题。
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.2.Final</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>0.2.0</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
1.3 在插件中配置Hibernate jpamodelgen
- 官网:hibernate.org/orm/tooling…
- baeldung示例:www.baeldung.com/hibernate-c…
在编绎阶段生成JPA的 Metamodel,然后可以使用hibernate critieria queries。
同样的,在maven-complier-plugin插件中配置:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</path>
<path>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>5.4.3.Final</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
其它依赖:spring-boot-starter-data-jpa,如何使用?
@SpringBootTest
public class CourseRepositoryTest {
@Autowired
private EntityManager entityManager;
@Test
public void test() {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Course> cq = cb.createQuery(Course.class);
Root<Course> root = cq.from(Course.class);
cq.select(root).where(cb.equal(root.get(Course_.id), 1));
TypedQuery<Course> query = entityManager.createQuery(cq);
List<Course> results = query.getResultList();
System.out.println(results);
}
}
1.4 其它
另外,maven-complier-plugin还可以与spring-boot-configuration-processor结合使用。具体如何使用可以参考:www.jb51.net/article/223…
2. maven-surefire-plugin
用于测试阶段的插件,那么为什么要显式的声明?
- 因为有时候需要跳过测试。
- 另一个显示声明的原因可能默认情况下,该插件只会运行特定格式的测试用例(如Test开头的类,或是Test/TestCase结尾的类),如果想要额外配置其它的测试类,可以在插件的configuration的includes中加额外的通配。
一般情况下会有两种:
- a. 还是会编绎测试代码但会跳过运行。
- b. 跳过测试代码的编绎和运行。
比如skipTests设为true,从官网注解上可以看出:
Set this to "true" to skip running tests, but still compile them.
这样做还是会编绎测试代码,但不会运行。与命令行mvn clean compile -DskipTests效果一样。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M7</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
另一种就是跳过测试代码的编绎与运行:
Set this to "true" to bypass unit tests entirely.
与命令行mvn clean compile -Dskip=true效果一样。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M7</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
3. maven-failsafe-plugin
官网:maven.apache.org/surefire/ma…
来自官网的解释:
The Failsafe Plugin is designed to run integration tests while the Surefire Plugin is designed to run unit tests.
即上述的maven-surefire-plugin设计出来用于运行单元测试,而本插件的目的是用作集成测试的配置。
总体上还是很迷惑,可以参考Stackoverflow上的贴子:stackoverflow.com/questions/2…
具体来说就是,上述的maven-surefire-plugin在mvn test阶段执行,即如果一个单元测试运行失败了,那么就只能到test阶段了。我们都知道maven运行的phase,是会包含当前以及之前的所有阶段。test阶段后面是package阶段,那么如果我们运行了mvn package,在maven-surefire-plugin遇到单元测试失败的时候,是无法进行package这一阶段的,而是会停在test阶段。
那么maven-failsafe-plugin是在verify阶段执行的,所以如果一个测试失败了,那么还是会打包成功的,因为verify阶段在package阶段的后面,但是会导致install阶段无法进行。
maven的所有phases:validate --> compile --> test --> package --> verify --> install --> deploy。
maven-surefire-plugin的配置和maven-surefire-plugin差不多:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.0.0-M7</version>
<configuration>
<includes>
<include>**/CucumberIT*.java</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
4. maven-checkstyle-plugin
- 官网:maven.apache.org/plugins/mav…
- Baeldung示例:www.baeldung.com/checkstyle-…
- 官网提供的check xml(基于sun和google的):github.com/checkstyle/…
- 基于阿里以及华为的check xml:www.jianshu.com/p/557b975ae…
这个插件可以帮助开发检测代码中不合规范的地方。
可以加在maven pom.xml:
- Report相关:在
reporting标签中加plugin,详细可参考官网示例:Using a Custom Checkstyle Checker Configuration,绑定两个goals:checkstyle:checkstyle:checkstyle分析以及生成xml等格式的报告。checkstyle:checkstyle-aggregate:checkstyle分析以及生成html报告。- 也可使用
mvn site来执行,执行完成后会在target/side目录下生成checkstyle.html文件。
- Build相关:在
build中加plugin,可以使用命令mvn checkstyle:check执行,或是在mvn install生命周期下也会生成checkstyle-result.xml,如果check失败了,会报错。
示例,我加了phase=validate, 这样就可以在validate生命周期下check:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<configLocation>sun_checks.xml</configLocation>
</configuration>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
比如我写了一个UserDomain,实现了equals方法却不实现hashCode()方法,那么checkstyle就会报错:
5. jacoco-maven-plugin
- 官网:www.jacoco.org/jacoco/trun…
- 官网Sample:www.jacoco.org/jacoco/trun…
- Baeldung示例:www.baeldung.com/jacoco
在测试方面,Code coverage(代码覆盖率)是一个很好的指标,我们可以使用jacoco插件来生成单元测试覆盖率的报告。
- 除了生成报告外,我们还可以加入一些rule,比如超过50%的覆盖率才算pass。
- 还可以在CI阶段和jenkins进行集成。
示例:
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.8</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>generate-code-coverage-report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
生成的报告示例:
6. spring-boot-maven-plugin
官网:docs.spring.io/spring-boot…
如果是传统web项目,我们会把项目打成war后,放入tomcat中启动。但如果我们的项目是Spring Boot项目,使用的是embed tomcat,那么我们一般会打包会一个可执行的jar,即:fat jar,通过命令java jar xxx.jar来启动项目。
spring-boot-maven-plugin可以帮助项目打包成一个fat jar。
<build>
<finalName>springboot-k8sdemo</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
7. build-helper-maven-plugin
默认情况下,maven支持一个src和一个test,比如:
|- src/main/java
|- com.maven.service
|- CalculatorService.java
|- test/java
|- com.maven.service
|- CalculatorServiceTest.java
如果需要支持多个source package,或是多个test package,或是多个resources,可以用这个插件指定。
比如想要多加一个source,我们可以使用以下configuration,把src/main/other这个路径也加为source目录:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>src/main/other</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
如此一来,我们在src/main/other下,有个com.xyz包,在mvn compile阶段也会被编绎:
8. sonar-maven-plugin
使用该插件执行sonar扫描。SonarQube 是一个开源的代码分析平台, 用来持续分析和评测项目源代码的质量。 通过SonarQube我们可以检测出项目中重复代码, 潜在bug, 代码规范,安全性漏洞等问题, 并通过SonarQube web UI展示出来。
参考:
- Sonarqube官网:www.sonarqube.org/
- baeldung示例:www.baeldung.com/sonar-qube
- 一篇写的很好的介绍:blog.csdn.net/zzhongcy/ar…
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.4.0.905</version>
</plugin>
</plugins>
</pluginManagement>
</build>