maven的理想:像一种什么设计模式?—模板方法模式

  • 自动走完标准的构建流程:清理 --> 编译 --> 測试 --> 报告 --> 打包 --> 部署
  • 统一入口,所有配置在一个pom里搞定

1.maven生命周期、阶段

maven有三个完全独立的生命周期(LifeCycle):Clean,Build,Site。每个生命周期都由一系列阶段(Phase)组成,执行其中某个阶段时,必须将当前周期的所有阶段执行完。LifeCycle和Phase具体的对应关系如下图:

【Maven】执行原理:生命周期、插件(及自定义插件示例)

各个生命周期的阶段(phase)定义如下:

阶段 处理 描述
验证 validate 验证项目 验证项目是否正确且所有必须信息是可用的
编译 compile 执行编译 源代码编译在此阶段完成
测试 Test 测试 使用适当的单元测试框架(例如JUnit)运行测试。
包装 package 打包 创建JAR/WAR包如在 pom.xml 中定义提及的包
检查 verify 检查 对集成测试的结果进行检查,以保证质量达标
安装 install 安装 安装打包的项目到本地仓库,以供其他项目使用
部署 deploy 部署 拷贝最终的工程包到远程仓库中,以共享给其他开发人员和工程

运行任何一个阶段,都会从其所在生命周期的第一个阶段开始,顺序执行到指定的阶段。比如,mvn package — 本义:执行default周期的package阶段,maven会自动从process-resources阶段开始运行到package阶段结束

maven的构建生命周期,只是一个抽象规范流程。周期内的每个阶段的执行,是交由plugin插件来完成

2.maven插件

插件plugin是绑定到生命周期,承担实际功能的组件。mvn运行时,自动关联插件来运行。下表是maven默认的各阶段对应的插件列表:

生命周期 生命周期阶段 插件目标 执行任务
clean pre-clean
clean maven-clean-plugin:clean 删除项目的输出目录
post-clean
site pre-site
site maven-site-plugin:site
post-site
site-deploy maven-site-plugin:deploy
default process-resources maven-resources-plugin:resources 复制主资源文件至主输出目录
compile maven-compiler-plugin:compile 编译主代码至主输出目录
process-test-resources maven-resources-plugin:testResources 复制测试资源文件至测试输出目
test-compile maven-compiler-plugin:testCompile 编译测试代码至测试输出目录
test maven-surefire-plugin:test 执行测试用例
package maven-jar-plugin:jar(ejb:ejb jar:jar rar:rar war:war) 创建项目jar包
install maven-install-plugin:install 将项目输出构件安装到本地仓库
deploy maven-deploy-plugin:deploy 将项目输出构件部署到远程仓库

另外,maven还可以自定义插件,来扩展maven的功能。

问题一:这些插件在哪里设置?

关于插件的配置一般是在pom文件的<plgin>标签中,具体关系是:<bulid>:<pluginManagement>:<plugins>:<plugin>。下图是关于maven默认插件和自定义插件的配置示例:

【Maven】执行原理:生命周期、插件(及自定义插件示例)
可以看到,默认插件是maven开头,没有execution这一项,不需要再手动绑定声明周期阶段。

问题二:如何执行maven中的这些插件?

命令格式一:mvn 插件name goal。比如:

  • mvn jetty:run
  • mvn com.xupt.yzh:my_maven_plugin:1.0-SNAPSHOT:log(下面的自定义插件示例)
  • 在执行命令时还可以传入参数,mvn com.xupt.yzh:my_maven_plugin:1.0-SNAPSHOT:log -D log.name=Lisi

1.LifeCycle、Phase、Plugin、Goal关系?

  • 一个LifeCycle包含多个Phase ,一个Phase绑定一个plugin ,一个 plugin 提供了一组可以被运行的 goal
  • 另外,从下面自定义插件就能看出,一个plugin是一个项目,而goal对应一个具体的实现类(运行实例)


2.Phase和Goal什么关系?
一个Phase包含多个goal,但区别在于执行 Phase 时必须把周期内的前置阶段也执行完,而插件可以单独执行某个或一组 goal。

命令格式二:mvn 生命周期阶段。比如下面这些常用命令:

  • mvn clean:清理旧的jar包
  • mvn compile:编译主程序
  • mvn package:打包当前项目
  • mvn install:安装jar到本地库,等于package+放到本地仓库

idea和eclipse生成项目最终也是依赖maven插件生成的,它们一般自带了默认插件,所以我们在idea的右侧 maven#LifeCycle 直接运行即可。另外,我们自己引入的插件(比如jetty)也是在maven插件栏运行(maven#plugins)。

问题三:如何自定义插件?

插件的开发步骤如下:

1.引入maven api的依赖,设置打包方式为maven-plugin

【Maven】执行原理:生命周期、插件(及自定义插件示例)
2. 编写简单Mojo类—继承AbstractMojo,并指定goal,然后打包插件。

【Maven】执行原理:生命周期、插件(及自定义插件示例)
3. 通过命令执行插件 mvn [plugin-name] [goal-name],在这里是

【Maven】执行原理:生命周期、插件(及自定义插件示例)

这里再提一点,一个插件可以绑定多个周期。

问题四:自定义插件可以传入参数吗?

可以的,可以通过@Parameter定义参数,并指定默认值

【Maven】执行原理:生命周期、插件(及自定义插件示例)
执行结果如下:

【Maven】执行原理:生命周期、插件(及自定义插件示例)
现在我在执行命令时通过 -D 传入参数。mvn com.xupt.yzh:my_maven_plugin:1.0-SNAPSHOT:log -D log.name=Lisi,执行结果如下:
【Maven】执行原理:生命周期、插件(及自定义插件示例)
虽然我们可以自定义插件,但在实际开发中,使用默认插件就完全够用了,自定义插件很少用到。

相关文章:

  • 2023-03-11
  • 2021-08-17
  • 2021-05-30
  • 2021-09-13
  • 2021-08-29
猜你喜欢
  • 2021-11-03
  • 2021-11-12
  • 2021-07-12
  • 2021-12-30
  • 2022-12-23
相关资源
相似解决方案