Maven是Java工程常用的项目管理工具,通过Maven可以管理项目的各个生命周期。Maven本质是一个插件框架,本身并不执行任何构建任务,所有的工作都是交给插件来完成的。熟练使用Maven插件,可以让我们的开发工作事半功倍,下面列出的都是我平时工作中常用插件的使用case,不会涵盖所有配置,但已使我现在的工作足够流畅。
一、maven-compiler-plugin
maven-compiler-plugin的compiler目标(goal)与编译生命周期阶段绑定。需要指定编译的jdk版本和编码,如:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.2</version> <configuration> <target>${jdk.version}</target> <source>${jdk.version}</source> <encoding>${project.build.sourceEncoding}</encoding> </configuration> </plugin>
二、maven-surefire-plugin
maven-surefire-plugin是用于测试的插件,对应的mvn命令是mvn test,执行这个命令将把test目录下的所有测试用例都跑一遍。如果只需要执行其中的一个测试类,使用mvn test -Dtest=测试类。2.7.3版本以上还支持执行单独的一个测试方法,命令行mvn test -Dtest=测试类#测试方法。大部分情况下,只要知晓上面的命令就已足够使用,不需要显示配置该插件,但是当需要忽略测试,指定某些测试用例,或者并行执行的时候,了解该插件的一些配置项就有必要了,如:
<!--Maven运行测试用例时,是通过调用maven的surefire插件并fork一个子进程来执行用例的。--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <!--2.7.3版本以上才可以指定执行单个测试方法--> <!--mvn clean test -Dtest=AppTest#dTest--> <version>2.18.1</version> <configuration> <!--忽略不执行测试--> <skipTests>true</skipTests> <!--指定要执行的测试用例--> <includes> <include>**/OtherTest.java</include> </includes> <!--forkmode属性中指明是要为每个测试创建一个进程,还是所有测试在同一个进程中完成。--> <!--pretest:每一个测试创建一个新进程--> <!--once:在一个进程中进行所有测试--> <!--always:在一个进程中并行的运行脚本--> <forkMode>always</forkMode> <!--threadCount:执行时,指定可分配的线程数量--> <parallel>methods</parallel> <threadCount>2</threadCount> <!--jvm参数 mvn clean test -Djava.io.tmpdir=logs--> <argLine>-Djava.io.tmpdir=logs</argLine> </configuration> </plugin>
三、exec-maven-plugin
java命令去执行应用程序最麻烦的就是classpath了,有了exec-maven-plugin这个插件,用mvn exec:exec命令去执行,就需要我们为classpath费脑筋了。执行前要先编译。
<plugin> <!--mvn clean compile;mvn exec:exec--> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.2.1</version> <configuration> <!-- 执行什么样的命令 --> <executable>java</executable> <arguments> <argument>-Djava.io.tmpdir=logs</argument> <!-- 工程的classpath并不需要手动指定,它将由exec自动计算得出 --> <argument>-classpath</argument> <classpath/> <argument>${main.class}</argument> <argument>arg1</argument> <argument>arg2</argument> </arguments> </configuration> </plugin>
四、maven-dependency-plugin
maven-dependency-plugin的作用是分析导入项目依赖,mvn dependency:tree,mvn dependency:analyze是分析依赖冲突的有效工具。copy-dependencies目标能将依赖的jar包从本地仓库中复制到特定目录下,这在项目打包时非常有用。
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>copy</id> <phase>package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory> <!--拷贝到构建目录的lib文件夹下--> ${project.build.directory}/lib </outputDirectory> </configuration> </execution> </executions> </plugin>
五、maven-resources-plugin
maven-resources-plugin插件的copy-resources目标能实现工程资源文件的拷贝,如:
<plugin> <artifactId>maven-resources-plugin</artifactId> <executions> <execution> <id>copy-resources</id> <phase>package</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <encoding>UTF-8</encoding> <!--拷贝到构建目录conf文件夹下--> <outputDirectory>${project.build.directory}/conf</outputDirectory> <resources> <resource> <directory>src/main/resources/conf</directory> <includes> <include>config.properties</include> </includes> <filtering>true</filtering> </resource> </resources> </configuration> </execution> </executions> </plugin>
六、maven-jar-plugin
这个插件提供了构建jar包的能力。配合前面介绍的maven-dependency-plugin和maven-resources-plugin,用下面这段配置我们可以构建一个配置文件在jar包外方便修改,指定了main class和classpath的工程jar包,基本可以拿来部署运行了。
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>2.5</version> <configuration> <archive> <!--自动添加META-INF/MANIFEST.MF--> <manifest> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> <mainClass>${main.class}</mainClass> </manifest> <manifestEntries> <Class-Path>.</Class-Path> </manifestEntries> </archive> <!--排除某些配置文件,放在jar的外面,方面修改--> <excludes> <exclude>**/conf/*.properties</exclude> </excludes> </configuration> </plugin>
七、maven-shade-plugin
如果依赖的项目比较少,可以选择把这些依赖都打进一个jar包里。
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <filters> <filter> <artifact>ocm.mogujie.union.maven:demo</artifact> <excludes> <exclude>**/conf/*.properties</exclude> </excludes> </filter> </filters> <transformers> <!--如果使用了spring,注意将spring各个版本的schemas都打进jar包中--> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/spring.handlers</resource> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/spring.schemas</resource> </transformer> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>${main.class}</mainClass> <manifestEntries> <Class-Path>.</Class-Path> </manifestEntries> </transformer> </transformers> </configuration> </execution> </executions> </plugin>
八、maven-assembly-plugin
如果是比较大型的应用,所有依赖都和项目代码打包成一个jar就显得不太合适了。maven-assembly-plugin用户制作项目分发包,包中可以包含项目的可执行jar,依赖,README,shell脚本等,依据自定义编写的描述文件,能够在文件夹,文件模式,模块级别控制打包,支持主要的包格式:zip、tar.gz、war、jar。
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>2.5</version> <configuration> <archive> <!--自动添加META-INF/MANIFEST.MF--> <manifest> <addClasspath>true</addClasspath> <mainClass>${main.class}</mainClass> </manifest> <manifestEntries> <Class-Path>..</Class-Path> </manifestEntries> </archive> <!--排除某些配置文件,放在jar的外面,方面修改--> <excludes> <exclude>**/conf/*.properties</exclude> </excludes> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>2.2.1</version> <executions> <execution> <id>assemble</id> <goals> <goal>single</goal> </goals> <phase>package</phase> </execution> </executions> <configuration> <descriptors> <descriptor>${project.basedir}/src/main/assembly/release.xml</descriptor> </descriptors> <finalName>${project.artifactId}-${project.version}</finalName> <outputDirectory>${project.build.directory}</outputDirectory> </configuration> </plugin>
打包描述文件release.xml:
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd"> <id>dist</id> <formats> <format>tar.gz</format> </formats> <includeBaseDirectory>false</includeBaseDirectory> <fileSets> <fileSet> <directory>.</directory> <outputDirectory>/</outputDirectory> <includes> <include>README*</include> </includes> </fileSet> <fileSet> <directory>src/main/assembly</directory> <outputDirectory>logs</outputDirectory> <excludes> <exclude>*</exclude> </excludes> </fileSet> <fileSet> <directory>./src/main/bin</directory> <outputDirectory>bin</outputDirectory> <includes> <include>**/*</include> </includes> <fileMode>0755</fileMode> </fileSet> <fileSet> <directory>src/main/resources/conf</directory> <outputDirectory>conf</outputDirectory> <includes> <include>config.properties</include> </includes> </fileSet> </fileSets> <dependencySets> <dependencySet> <outputDirectory>lib</outputDirectory> </dependencySet> </dependencySets> </assembly>
运行脚本start.sh
#!/bin/bash java -jar ../lib/demo-1.0-SNAPSHOT.jar