本博文不会长篇大论的讨论生命周期的概念, 而是从各种 plugin 的实际功能和应用出发, 来讨论 maven 的实际应用, 说得通透一点, 生命周期 (lifecycle) 可以理解成由各种 plugin 按照一定的顺序执行来完成 java 项目清理, 编译, 打包, 测试, 布署等整个项目的流程的一个过程.
生命周期 (lifecycle) 由各个阶段组成, 每个阶段由 maven 的插件 plugin 来执行完成. 生命周期 (lifecycle) 主要包括 clean,resources,complie,install,package,testResources,testCompile 等, 其中带 test 开头的都是用业编译测试代码或运行单元测试用例的.
总揽生命周期(lifecycle)
一般构建项目时执行的最常用的命领是 mvn clean install, 如果是 IDE 就是点对应的按纽其实还是调的 mvn 命令, 除非你使用的 IDE 内嵌的 maven(不推荐使用内嵌的 maven). 下周通过一个具体的实例来详细了解执行 mvn clean install 这条命令背后, maven 为我们做了哪些事情.
到项目根目录下执行 mvn clean install 对应的输出如下图所示
由上图可知, 各个插件的执行顺序一般是: 1:clean,2:resources,3:compile,4:testResources,5:testCompile,6:test,7:jar,8:install. 在图中标记的地方每一行都是由冒号分隔的, 前半部分是对应的插件, 后半部分是插件的执行目标也就是插件执行产生的结果. 现在我们来看下上面的 pom 文件, 我们如配置了 maven-compiler-plugin 这个插件, 其它的插件没有配置, 但最后项目构建成功, 说明 maven 内置的各种插件, 如果 pom 中没有配置就调用默认的内置插件, 如果 pom 中配置了就调用配置的插件. 到此我们理解 maven 的构建过程或者有更多的人称是打包, 就是由各种插件按照一定的顺序执行来完成项目的编译, 单元测试, 打包, 布署的完成. 各种插件的执行过程也就构成的 maven 的生命周期 (lifecycle). 生命周期(lifecycle) 各个阶段并不是独立的, 可以单独执行如 mvn clean, 也可以一起执行如 mvn clean install. 而且有的 mvn 命令其是包括多个阶段的, 如 mvn compile 其是包括了 resources 和 compile 两个阶段. 下面分别来分析各个阶段需要的插件和输出的结果.
clean 插件 maven-clean-plugin:2.5
clean 阶段是独立的一个阶段, 功能就是清除工程目前下的 target 目录, 对应的插件是 maven-clean-plugin:2.5,2.5 是版本号, 可以使用 maven 内置的插件, 当然也可以自己在 pom 中配置, 配置方式和上面所说的 maven-compiler-plugin 配置方式一样. 下面看下 mvn 执行前后工程目录下的输出对比.
resources 插件 maven-resources-plugin:2.6
resource 插件的功能就是把项目需要的配置文件拷贝到指定的目当, 默认是拷贝 src\main\resources 目录下的件到 classes 目录下, 当然可以自己来配置源目录和输出目录. resources 插件一般不单独执行, complie 插件执行时会先调用 resources 插件. 配置示例如下:
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-resources-plugin</artifactId>
- <version>2.6</version>
- <executions>
- <execution>
- <id>copy-resources</id>
- <!-- 在 default 生命周期的 validate 阶段就执行 resources 插件的 copy-resources 目标 -->
- <phase>validate</phase>
- <goals>
- <goal>copy-resources</goal>
- </goals>
- <configuration>
- <!-- 指定 resources 插件处理资源文件到哪个目录下 -->
- <outputDirectory>${project.build.outputDirectory}</outputDirectory>
- <!-- 也可以用下面这样的方式(指定相对 url 的方式指定 outputDirectory) <outputDirectory>target/classes</outputDirectory> -->
- <!-- 待处理的资源定义 -->
- <resources>
- <resource>
- <!-- 指定 resources 插件处理哪个目录下的资源文件 -->
- <directory>src/main/${deploy.env}/applicationContext.xml</directory>
- <!-- 指定不需要处理的资源 <excludes> <exclude>web-INF/*.*</exclude> </excludes> -->
- <!-- 是否对待处理的资源开启过滤模式 (resources 插件的 copy-resources 目标也有资源过滤的功能, 这里配置的
- 这个功能的效果跟 < build><resources><resource > 下配置的资源过滤是一样的, 只不过可能执行的阶段不一样, 这里执行的阶段是插件指定的 validate 阶段,<build><resources><resource > 下的配置将是在 resources 插件的 resources 目标执行时起作用(在 process-resources 阶段)) -->
- <filtering>false</filtering>
- </resource>
- </resources>
- </configuration>
- <inherited></inherited>
- </execution>
- </executions>
- </plugin>
- View Code
compile 插件 maven-compiler-plugin
compile 插件执行时先调用 resouces 插件, 功能就是把 src\mainjava 源码编译成字节码生成 class 文件, 并把编译好的 class 文件输出到 target\classes 目录下. 下面看执行结果:
单元测试所用插件
单元测试所用的 compile 和 resources 插件和主代码是相同的, 但执行的目标不行, 目标 testCompile 和 testResources 是把 src\test\java 下的代码编译成字节码输出到 target\test-classes, 同时把 src\test\resources 下的配置文件拷贝到 target\test-classes. 看下面的输出:
插件 maven-surefire-plugin:2.12.4 是执行单元测试类的, 在本例中就是运行 HelloWorldTest.testSayHello()方法, 如果单测试不通行, 构建会失败, 在编译正式的项目时可以使用 mvn -Dmaven.test.skip=true 来跳过测试类的编译和运行过程. mvn test 可以单独执行, 但是这个命令其实是包括了 resources,compile,testResources,testCompile,test 这几个阶段, 如下图所示:
打包插件
这个插件是把 class 文件, 配置文件打成一个 jar(war 或其它格式)包. 依赖包是不在 jar 里面的, 需要建立 lib 目录, 且 jar 和 lib 目录在同级目录. 常用的打包插件有 maven-jar-plugin,maven-assembly-plugin,maven-shade-plugin 三种, 下面分别介绍下各自己 pom 配置和使用特点.
maven-jar-plugin
可执行 jar 与依赖包是分开, 需建立 lib 目录里来存放需要的 j 依赖包, 且需要 jar 和 lib 目录在同级目录.
maven-assembly-plugin
这个插件可以把所有的依赖包打入到可执行 jar 包. 但是该插件有个 bug 会缺失 spring 的 xds 文件, 导致无法运行 jar, 同时如果同级目录还有其它可执行 jar 文件依赖可能会产生冲突.
maven-shade-plugin
所有的依赖包打入到可执行 jar 包, 如果同级目录有其它可执行 jar, 依赖可能会产生冲突, 且运行 jar 时, 有时会出现 SF,DSA,RSA 文件冲突的提示, 需要排除 META-INF 目录下的文件.
发布插件 maven-install-plugin
发布插件的功能就是把构建好的 artifact 部署到本地仓库, 还有一个 deploy 插件是将构建好的 artifact 部署到远程仓库.
来源: http://www.bubuko.com/infodetail-3392800.html