一 maven 框架
maven官方文档介绍Apache Maven 2.2.x是一个项目开发和集成的工具,它建立在项目模型对象(PMO)基础之上,所有构建、依赖管理、文档创建、站点发布, 分发都在pom.xml文件中控制. Maven是可以用插件来扩展。它的框架如下:(2.2.x)
maven3.x框架结构如下
二 Maven属性
使用插件来扩展maven功能,必须先了解maven可访问的属性,maven属性在前一小节已经有过简单介绍,这里再展开讨论下。
在pom.xml中可以使用Maven属性,格式为${属性名},在Maven项目中可以使用隐式属性如project.*(应用pom文件中project属性),setting.*(访问setting.xml文件中属性),env.*(访问环境变量属性,如path和MAVEN_HOME),系统属性(通过java中System.getProperty()能拿到的属性)。下面分别介绍这些属性:
1 项目属性
当你使用该隐式变量引用属性的时候,你实际上正在使用简单的点标记来引用Model对象的一个bean属性。例如,当你引用0.6-SNAPSHOT的时候,你实际上是在调用暴露出来的Model对象实例的getVersion()方法。任何在Maven POM 中的东西都可以用属性来引用,比如pom.xml中有
<groupId>org.sonatype.group1</groupId> <artifactId>sibling-project</artifactId> <version>0.6-SNAPSHOT</version>
project.groupId 和 project.version 分别为org.sonatype.group1和0.6-SNAPSHOT
在一个POM中有数百的属性可以引用,具体可以参考pom的完整结构http://maven.apache.org/ref/2.2.1/maven-model/apidocs/index.html,查看org.apache.maven.model这个类的javadoc文档,能够找到想要的项目属性。
2 setting属性
任何Maven本地Settings文件的属性都可以被引用,该文件通常位于~/.m2/settings.xml。这个文件包含了用户特定的配置,如本地仓库的位置,以及由某个特定用户配置的服务器,profile,和镜像,setting的具体属性可以参考http://maven.apache.org/ref/2.2.1/maven-settings/index.html中Maven Settings Model的javadoc
3 环境变量属性
env.PATH, env.HOME, env.JAVA_HOME, env.MAVEN_HOME
虽然他们都是可用的,但如果你有选择,你更应该使用Java系统属性
4 Java系统属性
Maven暴露所有来自于java.lang.System的属性。任何你能从System.getProperty()获取的属性都能以Maven属性的形式引用
java.version | Java运行环境版本 | java.vendor | Java运行环境供应商 |
java.vendor.url | Java供应商URL | java.home | Java安装目录 |
java.vm.specification.version | Java虚拟机规格说明版本 | java.vm.specification.vendor | Java虚拟机规格说明供应商 |
java.vm.specification.name | Java虚拟机规格说明名称 | java.vm.version | Java虚拟机实现版本 |
java.vm.vendor | Java虚拟机实现供应商 | java.vm.name | Java虚拟机实现名称 |
java.specification.version | Java运行环境规格说明版本 | java.specification.vendor | Java运行环境规格说明供应商 |
java.specification.name | Java运行环境规格说明名称 | java.class.version | Java类格式版本号 |
java.class.path | Java类路径 | java.ext.dirs | 扩展目录的路径 |
os.name | 操作系统名称 | os.arch | 操作系统架构 |
os.version | 操作系统版本 | file.separator | 文件分隔符(UNIX上是"/",Windows上是"\") |
path.separator | 路径分隔符(UNIX上是":",Windows上是";") | line.separator | 行分隔符(在UNIX和Windows上都是"\n") |
user.name | 用户帐户名称 | user.home | 用户home目录 |
user.dir | 用户当前工作目录 |
5 用户定义属性
这类属性可以定义在POM或者Profile中,而这些在POM或者MavenProfile中设置的属性可以像任何其它Maven属性一样被引用。
<properties> <arbitrary.property.a>This is some text</arbitrary.property.a> <hibernate.version>3.3.0.ga</hibernate.version> </properties>
<profiles> <profile> <id>some-profile</id> <properties> <arbitrary.property>This is some text</arbitrary.property> </properties> </profile> </profiles>
在资源中引用属性,可以使用外部资源文件,如开启maven的filter过滤资源,默认maven的filter文件路径为src/main/filters/目录,也可以在pom中设置到其他路径,比如想用default.properties的属性替换掉资源文件里的占位符,目录路径为:
service.xml内容为:
<?xml version="1.0" encoding="UTF-8"?> <service> <!-- This URL was set by project version 0.6-SNAPSHOT --> <url>${jdbc.url}</url> <user>${jdbc.username}</user> <password>${jdbc.password}</password> </service> </xml>
default.properties内容为:
jdbc.url=jdbc:hsqldb:mem:mydb jdbc.username=admin jdbc.password=
pom.xml filter设置为:
<project> .... <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> .... <build> <finalName>simple-webapp</finalName> <filters> <filter>src/main/filters/default.properties</filter> </filters> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> </build> .... </project>
开启资源过滤后(资源过滤默认是关闭的),运行mvn resources:resources后,target目录下target\classes\META-INF\service.xml占位符会被properties文件具体值替换掉。
三 maven 插件
1 反转控制(IOC)
Maven的心脏是一个名为Plexus的反转控制(IoC)框架,它是一个用来管理及关联组件的系统。用Java实现的IoC容器中,最重要的一个功能是称作依赖注入的机制。IoC的基本想法是将对象的创建和管理从代码中剥离,并将控制放到IoC框架手中。在一个面向接口编程的应用程序中使用依赖注入,你创建的组件可以不与任何特定的接口实现绑定。你的程序也针对接口编程并通过配置Plexus来将正确的实现连接到正确的组件。虽然你的代码都是与接口打交道,但你仍然可以通过一个定义组件的XML文件来获得类和组件相互依赖的信息。换句话说,你可以编写独立的组件,然后你可以通过一个XML文件来定义组件应当如何被装配在一起。在Plexus的情形中,定义系统组件的XML文档位于META-INF/plexus/components.xml。在一个Java IoC容器中,有很多中方法将依赖值注入到一个组件对象中:构造器,set方法,或者字段注入。虽然Plexus提供全部这三种依赖注入技术,Maven只使用其中的两种:字段注入和set方法注入。
目前Spring是最流行的IoC容器。它影响了Java的“生态系统”,迫使如SunMicrosystems之类的公司让出更多的对于开源社区的控制,并通过提供一个更易插入的,面向组件的“总线”来帮助开发一些标准,当Maven被创建的时候,Spring并不是一个成熟的选项。最初的Maven提交者团队更熟悉Plexus因为正是他们发明了Plexus,因此他们决定使用Plexus做为Ioc容器。虽然它没有Spring Framework流行,但并不是说它的功能没那么强大。
2 插件
一个Maven插件是包含了一个插件描述符和一个或者多个Mojo的Maven构件。一个Mojo可以被认为是Maven中的一个目标,每一个目标对应了一个Mojo。compiler:compile目标对应了Maven Compiler插件的CompilerMojo类,jar:jar目标对应了Maven Jar插件的JarMojo类。当你编写自己的插件的时候,你在一个单独的插件构件中将一组相互关联的Mojo(或者目标)归类。(Maven使用术语Mojo因为这是一个对于Pojo(Plan-oldJava Object)的玩笑),Mojo不仅仅是Maven中的一个目标,它是一个由Plexus管理的组件,可以引用其它Plexus组件。
1)插件描述符
Maven插件包含了一个告诉Maven各种Mojo和插件配置的路线图。这就是插件描述符,它位于JAR文件中的META-INF/maven/plugin.xml。当Maven载入一个插件的时候,它读取该XML文件,初始化并配置插件对象,使Mojo被包含在插件中,供Maven使用。当你编写自定义Maven插件的时候,你几乎不需要编写插件描述符。在构 建生命周期中,绑定到maven-plugin打包类型的生命周期目标显示,plugin:descriptor目标被绑定到了generate-resources生命周期阶段。该目标根据插件源码中的注解生成一个插件描述符,plugin.xml定义三部分内容:坐标信息、mojo声明、依赖声明。
description | 该元素包含了插件的简短描述。 |
groupId, artifactId, version | 就像Maven中的任何其它构件一样,插件也需要唯一的坐标 |
goalPrefix | 该元素(目标前缀)用来设置某个特定插件用来引用目标的前缀 |
isolatedRealm | 该遗留属性不再被Maven使用。它的存在是为了给旧的插件提供向后兼容性早期版本的Maven。使用它提供一种在单独ClassLoader中载入插件依赖的机制 |
inheritedByDefault | 如果inheritedByDefault(缺省继承)被设置成true,所有在父项目配置的该插件的mojo会在子项目中生效inheritedByDefault没有被设置成true,那么定义在父项目中的目标执行不会被子项目继承 |
mojo配置 | |
goal | 这是目标的名称。如果你在运行compiler:compile目标,compiler就是插件的goalPrefix,compile就是目标的名称。 |
description | 目标的简要描述,当用户使用Help插件生成插件文档的时候,该描述会被显示 |
requiresDirectInvocation | 如果你将其设置成true,那么该目标就只能由用户在命令行显示的执行。如果有人想要将该目标绑定到一个生命周期阶段,Maven会打印错误信息。该元素默认值是false。 |
requiresProject | 指定该目标不能在项目外部运行。目标需要一个带有POM的项目。requiresProject默认的值为true。 |
requiresReports | 如果你正创建一个插件,它依赖于报告,那么你就需要将requiresReports设置成true。例如,如果你创建一个插件用来聚合许多报告的信息,那么就需要将requiresReports设置成true。该元素默认的值为false。 |
aggregator | 当Mojo描述符的aggregator设置成true的时候,那么该目标只会在Maven执行的时候运行一次,提供该配置是为了让开发人员能够对一系列构建进行总结;例如,创建一个插件来概述构建中所有项目的一类报告。一个aggregator设置成true的目标应该只在Maven构建的顶层项目中运行。aggregator默认值是false。 |
requiresOnline | 指定当Maven在离线模式(-o命令行选项)的时候该目标不能运行,该元素默认值是false |
inheritedByDefault | 如果inheritedByDefault被设置成true,在父项目中配置的mojo就会同样在子项目中被继承 |
phase | 如果用户没有为该目标绑定一个阶段,那么该元素定义一个mojo默认的阶段,若你没有指定phase元素,Maven就会要求用户在POM中显式的指定一个阶段 |
implementation | 该元素告诉Maven需要为该Mojo初始化什么类,这是一个Plexus组件属性(在Plexus ComponentDescriptor 中定义) |
language | Maven Mojo默认的语言是java,该配置控制Plexus ComponentFactory初始化该Mojo组件 |
instantiationStrategy | 该属性是一个Plexus组件配置属性,它告诉Plexus如何创建和管理组件实例,Maven中,所有mojo的instantiationStrategy都被配置成per-lookup,每次Maven从Plexus获取该mojo的时候,一个新的实例被创建 |
executionStrategy | executionStrategy告诉Maven什么时候,怎样运行一个Mojo,once-per-session和always,是早期版本遗留的 |
parameters | 该元素描述Mojo的所有参数。name,type,required,editable(是否允许在pom.xml中设置),description |
configuration | (为所有Mojo参数提供默认值) |
requirements | 一个mojo是一个由Plexus管理的组件,它就有机会引用Plexus管理的其它组件。该元素能让你定义对于其它Plexus组件的依赖 |
2)编写插件
a)创建插件项目:
mvn archetype:create -DgroupId=org.sonatype.plugins -DartifactId=first-maven-plugin -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-mojo
运行mvn install 后,可以打开jar包(或者class目录中META-INF\maven)下pugin.xml插件描述文件:
<?xml version="1.0" encoding="UTF-8" ?> - <plugin> <description /> <groupId>org.sonatype.plugins</groupId> <artifactId>first-maven-plugin</artifactId> <version>1.0-SNAPSHOT</version> <goalPrefix>first</goalPrefix> <isolatedRealm>false</isolatedRealm> <inheritedByDefault>true</inheritedByDefault> - <mojos> - <mojo> <goal>touch</goal> <description>Goal which touches a timestamp file.</description> <requiresDirectInvocation>false</requiresDirectInvocation> <requiresProject>true</requiresProject> <requiresReports>false</requiresReports> <aggregator>false</aggregator> <requiresOnline>false</requiresOnline> <inheritedByDefault>true</inheritedByDefault> <phase>process-sources</phase> <implementation>org.sonatype.plugins.MyMojo</implementation> <language>java</language> <instantiationStrategy>per-lookup</instantiationStrategy> <executionStrategy>once-per-session</executionStrategy> - <parameters> - <parameter> <name>outputDirectory</name> <type>java.io.File</type> <required>true</required> <editable>true</editable> <description>Location of the file.</description> </parameter> </parameters> - <configuration> <outputDirectory implementation="java.io.File">${project.build.directory}</outputDirectory> </configuration> </mojo> </mojos> - <dependencies> - <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-plugin-api</artifactId> <type>jar</type> <version>2.0</version> </dependency> </dependencies> </plugin>
描述文件中显示有可运行的目标touch,且输入参数值为maven的project.build.directory 参数。
运行插件的touch目标 mvn org.sonatype.plugins:first-maven-plugin:touch 结果可以验证touch创建文件是否成功。
3)插件前缀
运行插件时需要带上插件的goupId,artifactId,version,目标,参数,尤其groupId和aritifaceId比较长,mavne提供了缩写方式,即可以自定义插件前缀。
如果未使用其他仓库,可以在本地Maven仓库径org/apache/maven/plugins/maven-metadata-central.xml文件中看到插件组org.apache.maven.plugins的Maven元数据
<?xml version="1.0" encoding="UTF-8"?> <metadata> <plugins> <plugin> <name>Maven Clean Plugin</name> <prefix>clean</prefix> <artifactId>maven-clean-plugin</artifactId> </plugin> <plugin> <name>Maven Compiler Plugin</name> <prefix>compiler</prefix> <artifactId>maven-compiler-plugin</artifactId> </plugin> <plugin> <name>Maven Surefire Plugin</name> <prefix>surefire</prefix> <artifactId>maven-surefire-plugin</artifactId> </plugin> ... </plugins> </metadata>
如果使用了其他仓库,比如setting.xml中配置了
<pluginGroups>
<pluginGroup>com.xxx.org.apache.maven.plugins</pluginGroup>
<pluginGroup>com.my.maven.plugins</pluginGroup>
那么可以在本地仓库com\my\maven\plugins\maven-metadata-central.xml中查看插件组的元数据.
如果想要通过first:touch命令就能运行first-maven-plugin的touch目标,如所示,添加org.sonatype.plugins groupId至你的~/.m2/settings.xml文件中。这会让Maven优先扫描org.sonatype.plugins插件组
<settings> ... <pluginGroups> <pluginGroup>org.sonatype.plugins</pluginGroupd> </pluginGroups> </settings>这样子行得通是因为我们遵循了Maven插件的命名约定。如果你的插件有一个artifactId,并且它遵循模式maven-first-plugin,或者first-maven-plugin。Maven就会自动为你的插件赋予前缀first。换句话说,当Maven Plugin插件为你的插件生成插件描述符的时候,你不需要显式的为你的项目设定goalPrefix,###artifactId########,##plugin:descriptor目标会从你插件的artifactId中抽取前缀。${prefix}-maven-plugin, 或 maven-${prefix}-plugin,如果要显示配置插件,在插件pom.xml中配置
<build> <plugins> <plugin> <artifactId>maven-plugin-plugin</artifactId> <version>2.3</version> <configuration> <goalPrefix>blah</goalPrefix> </configuration> </plugin> </plugins> </build>
如果在~/.m2/settings.xml中的pluginGroups下添加了org.sonatype.plugins元素,你就应该能够在任何目录通过mvn blah:touch命令运行MyMojo
4)插件类注解
注解列表,可以用到Mojo类上
@goal <goalName> | 这是唯一必需的注解,它给予目标一个在插件中唯一的名称 | @requiresDependencyResolution <requireScope> | 标记该mojo在可以运行之前,需要特定范围或者一个暗指的范围)的依赖。支持的范围有compile,runtime,和test。如果该注解有一个值为test,那么就是告诉Maven,除非测试范围的所有依赖都被正确解析了,否则该mojo不能运行。 | |||
@requiresProject (true|false) | 标记该mojo必须在一个项目中运行,默认为true。这一点插件类型和骨架类型(archetype)相反,后者默认为false。 | @requiresReports (true|false) | 如果你正创建一个依赖于报告的项目,你就需要将requiresReports设置成true。该注解默认的值是false。 | |||
@aggregator (true|false) | 一个aggregator设置成true的Mojo在Maven运行的时候只会被执行一次,例如,创建一个插件用来汇总一次构建包含的所有项目的报告。aggregator设置成true的目标只针对Maven构建的顶层项目运行。该注解默认的值是false | @requiresOnline (true|false) | 当该注解的值是true的时候,Maven在脱机模式运行的时候该目标运行就败。Maven会抛出一个错误。默认值:false。 | |||
@requiresDirectInvocation | 当设置成true的时候,只有当用户显式的从命令行触发的时候,该插件才能得以执行。如果有人试图将其绑定到一个生命周期阶段,Maven就会抛出一个错默认值是false | @phase <phaseName> | 该注解指定目标默认的生命周期阶段。如果你将该目标的执行配置到了pom.xml而且没有指定一个阶段。Maven就会使用该注解的值将其绑定到一个默认的阶段 | |||
@execute [goal=goalName|phase=phaseName [lifecycle=lifecycleId]] |
该注解有很多种使用方式。 @execute goal="<goal>" 会在执行当前目标之前运行声明的目标。目标名称使用prefix:goal标记指定。 @execute phase="<phase>"在执行当前生命周期之前,fork出另一个构建生命周期(直到指定的阶段)。如果没有指定生命周期,Maven会使用当前构建的生命周期 @execute lifecycle="<lifecycle>" phase="<phase>"会执行给定的生命周期。自定义的生命周期可以在META-INF/maven/lifecycle.xml中定义。 |
@execute phase="package" lifecycle="zip" | @execute phase="compile" | @execute goal="zip:zip" |
到Maven并没有使用Java 5的标准注解。而是使用了Commons Attributes6。在注解成为Java语言的一部分之前,CommonsAttributes为Java程序员提供了一种使用注解的方式。因为Maven必须支持Java比较老的版本,所以它不能使用任何Java 5的新特性。
4)mojo执行失败
当mojo的execute方法失败时,Mojo中的execute()方法抛出两个异会抛出两钟异常:
ojoExecutionException:一个MojoExecutionException应该是一个致命的异常,发生了一些不可恢复的错误。如果有什么事情导致构建完全终止,你就需要抛出一个MojoExecutionException;比如说你正试图往磁盘写数据,但没有可用空间。你希望停止构建并让用户看到“BUILD ERROR”信息。
MojoFailureException:相对没有那么严重。一个单元测试可以失败,或者MD5校验和可以失败;两者都是潜在的问题,但是你不会想要抛出一个异常去终止整个构建,当Maven遇到项目失败的时候,他会提供不同的“弹性”设置:
mvn -ff
最快失败模式:Maven会在遇到第一个失败的时候失败(停止)。
mvn -fae
最后失败模式:Maven会在构建最后失败(停止)。如果Maven refactor中一个
失败了,Maven会继续构建其它项目,并在构建最后报告失败。
mvn -fn
从不失败模式:Maven从来不会为一个失败停止,也不会报告失败。
5)Mojo参数
在mojo中可以使用注解来绑定参数,如
/** * Any Object to print out. * @parameter * expression="${echo.message}" * default-value="Hello Maven World" */ private Object message;
参数message 绑定表达式为echo.message,如果mvn命令中传入 -Decho.message=aaa,那么aaa值将会赋给message参数。默认参数值取的是"Hello Maven World",默认参数值也可以取maven自带参数表达式。将值传给参数的方法,除了命令行之外,还可以在pom.xml或setting.xml中自定义,如:
<properties> <echo.message>Hello Everybody</echo.message> </properties>
还可以在pom的plugin中加入,如:
<build> <plugins> <plugin> <groupId>org.sonatype.mavenbook.plugins</groupId> <artifactId>first-maven-plugin</artifactId> <version>1.0-SNAPSHOT</version> <configuration> <message>Hello Everybody!</message> </configuration> </plugin> </plugins> </build>
如果我们想要在一个生命周期的不同阶段中运行EchoMojo两次,并且希望每次运行都能自定义message参数,我们可以在如下在POM中的execution级别配置这个参数值:
<build> <plugins> <plugin> <groupId>org.sonatype.plugins</groupId> <artifactId>first-maven-plugin</artifactId> <version>1.0-SNAPSHOT</version> <executions> <execution> <id>first-execution</id> <phase>generate-resources</phase> <goals> <goal>echo</goal> </goals> <configuration> <message>The Eagle has Landed!</message> </configuration> </execution> <execution> <id>second-execution</id> <phase>validate</phase> <goals> <goal>echo</goal> </goals> <configuration> <message>0.6-SNAPSHOT</message> </configuration> </execution> </executions> </plugin> </plugins> </build>
要配置一个多值的Mojo参数,你应该为这类参数使用一组元素。如果这个多值参数的名称是includes,你就可以使用一个includes元素,它包含一组include子元素。如果这个多值参数的名称是excludes,你就应该使用带有exclude子元素的excludes元素。要配置ZipMojo使其忽略所有以.txt及波浪号结尾的文件,你可以使用如下的插件配置。如:
<build> <plugins> <plugin> <groupId>org.sonatype.plugins</groupId> <artifactId>zip-maven-plugin</artifactId> <configuration> <excludes> <exclude>**/*.txt</exclude> <exclude>**/*~</exclude> </excludes> </configuration> </plugin> </plugins> </build>
其中zip插件的源码为:
/** * Zips up the output directory. * @goal zip * @phase package */ public class ZipMojo extends AbstractMojo { /** * The Zip archiver. * @parameter expression="${component.org.codehaus.plexus.archiver.Archiver#zip}" */ private ZipArchiver zipArchiver; /** * Directory containing the build files. * @parameter expression="/usr/local/hudson/hudson-home/jobs/maven-guide-zh-to-production/*/ private File buildDirectory; /** * Base directory of the project. * @parameter expression="/usr/local/hudson/hudson-home/jobs/maven-guide-zh-to-production/*/ private File baseDirectory; /** * A set of file patterns to include in the zip. * @parameter alias="includes" */ private String[] mIncludes; /** * A set of file patterns to exclude from the zip. * @parameter alias="excludes" */ private String[] mExcludes; public void setExcludes( String[] excludes ) { mExcludes = excludes; } public void setIncludes( String[] includes ) { mIncludes = includes; } public void execute() throws MojoExecutionException { try { zipArchiver.addDirectory( buildDirectory, includes, excludes ); zipArchiver.setDestFile( new File( baseDirectory, "output.zip" ) ); zipArchiver.createArchive(); } catch( Exception e ) { throw new MojoExecutionException( "Could not zip", e ); } } }
6)依赖于一个Plexus组件
一个Mojo是一个由名为Plexus的Ioc容器管理的组件。Mojo可以通过使用@parameter#@component注解声明Mojo参数,然后依赖于其它Plexu管理的组件,ZipMojo使用@parameter注解依赖于一个Plexus组件,该依赖也可以使用@component注解来声明。如
/** * The Zip archiver. * @component role="org.codehaus.plexus.archiver.Archiver" roleHint="zip" */ private ZipArchiver zipArchiver;
当Maven初始化该Mojo的时候,它会尝试通过指定的role和role hint来获取Plexus组件。在该例中,这个Mojo关联到一个ZipArchiver组件,后者能帮助ZipMojo创建ZIP文件。
maven的plugin插件有个descriptor目标绑定到了generate-resources阶段,该目标根据Mojo的注解生成插件描述符。有下列注解可以用在参数上,虽然也可以在公有setter方法上使用这些注解,不过一般是使用在私有变量上:
@parameter [alias="someAlias"] [expression="${someExpression}"] [defaultvalue="value"]
@required
@readonly:如果使用该注解,用户就不能从POM直接配置这个参数
@component:告诉Maven使用Plexus组件填充该字段。一个正确的@component注解值如下: @component role="org.codehaus.plexus.archiver.Archiver" roleHint="zip"
也可以使用@parameter expression="${component.org.codehaus.plexus.archiver.Archiver#zip}"
@deprecated:该参数以过期,不再推荐使用。
7)创建自定义的生命周期
自定义生命周期必须在插件项目的META-INF/maven/lifecycle.xml文件中定义。你可以引入这个定义在src/main/resources下的META-INF/maven/lifecycle.xml文件
结合例子看下:项目目录结构如下
package org.mtp.plugins; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; /** * 使用execute注解使用touch生命周期的goal * @goal after-touch * @execute lifecycle="touchcycle" phase="package" */ public class MyAfterLifeCycleMojo extends AbstractMojo{ @Override public void execute() throws MojoExecutionException, MojoFailureException { getLog().info("begin MyAfterLifeCycleMojo."); getLog().info("end MyAfterLifeCycleMojo."); } } package org.mtp.plugins; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; /** * 在 after-touch 目标之后执行此mojo * @goal after-cycle * @execute goal="after-touch" */ public class MyAfterMojo extends AbstractMojo{ @Override public void execute() throws MojoExecutionException, MojoFailureException { getLog().info("begin MyAfterMojo."); getLog().info("end MyAfterMojo."); } } package org.mtp.plugins; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; /** * 在生命周期阶段compiles之后执行 * @goal after-phase-resouces * @execute phase="compile" */ public class MyAfterPhaseMojo extends AbstractMojo{ @Override public void execute() throws MojoExecutionException, MojoFailureException { getLog().info("begin MyAfterPhaseMojo."); getLog().info("end MyAfterPhaseMojo."); } } //MyMojo在上文中已经列出lifecycle.xml内容为:
<lifecycles> <lifecycle> <id>touchcycle</id> <phases> <phase> <id>package</id> <executions> <execution> <goals> <goal>touch</goal> </goals> </execution> </executions> </phase> </phases> </lifecycle> </lifecycles>
mvn install之后,可以分别运行几个goal看看效果
mvn blabla:after-cycle 会触发after-touch goal,after-touch会触发touchcycle的package,它会触发touch目标,所以执行的Mojo依次是MyMojo,MyAfterLifeCycleMojo,MyAfterMojo
mvn blabla:after-phase-resouces 会先触发compile阶段之前所有绑定的插件,所以触发结果为:
[INFO] Scanning for projects... [INFO] Searching repository for plugin with prefix: 'blabla'. [INFO] ------------------------------------------------------------------------ [INFO] Building first-maven-plugin Maven Mojo [INFO] task-segment: [blabla:after-phase-resouces] [INFO] ------------------------------------------------------------------------ [INFO] Preparing blabla:after-phase-resouces [INFO] [plugin:descriptor {execution: default-descriptor}] [WARNING] Goal prefix is: blabla; Maven currently expects it to be first [INFO] Using 2 extractors. [INFO] Applying extractor for language: java [INFO] Extractor for language: java found 4 mojo descriptors. [INFO] Applying extractor for language: bsh [INFO] Extractor for language: bsh found 0 mojo descriptors. [INFO] [resources:resources {execution: default-resources}] [WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e . build is platform dependent! [INFO] Copying 1 resource [INFO] [compiler:compile {execution: default-compile}] [INFO] Nothing to compile - all classes are up to date [INFO] [blabla:after-phase-resouces {execution: default-cli}] [INFO] begin MyAfterPhaseMojo. [INFO] end MyAfterPhaseMojo. [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL
相关推荐
在Java开发领域,Maven是一个广泛使用的项目管理工具,它帮助开发者构建、管理和部署应用程序。...`demo-maven-plugin`和`mavenplugintest`这两个文件为我们提供了一个实践和学习Maven插件开发的实例。
- 为了支持更广泛的Maven插件,m2e提供了扩展点,允许第三方开发者为特定的Maven插件开发适配器。 9. **问题排查与资源**: - 如果遇到问题,开发者可以查阅官方文档,或者在Eclipse社区和Maven社区寻求帮助。 -...
Maven插件通常针对特定的任务进行封装,比如编译Java源代码、生成项目文档等。这种方式允许开发者在不同的项目之间共享构建逻辑,降低了重复工作的量。 **1.5 一个“项目”的概念模型** Maven将项目视为一系列相...
Eclipse作为流行的Java集成开发环境,为了方便开发者使用Maven,提供了Maven插件。本篇文章将详细解析如何在Eclipse中离线安装Maven插件,同时提供内附的Maven插件包,以解决在线安装过程中的速度问题和可能遇到的...
总之,MyEclipse集成Maven插件为开发者提供了更高效的工作环境,使得在IDE内就能完成大部分项目管理和构建任务,提高了开发效率。通过熟悉和掌握这些知识,可以更好地利用MyEclipse和Maven提升软件开发质量。
Eclipse的Maven插件是开发Java项目时不可或缺的工具,它将强大的Maven构建系统与流行的Eclipse集成开发环境(IDE)相结合,为开发者提供了一站式解决方案。Maven是一个项目管理和综合工具,它通过定义项目的结构和...
总结来说,MyEclipse 6.5的Maven插件是Java开发者必备的工具之一,它简化了项目构建和依赖管理,提高了开发效率,而其离线安装和良好的拔插性更是为不同环境下的开发工作提供了便利。正确理解和熟练使用Maven插件,...
然而,在某些网络环境不佳的情况下,Eclipse可能无法通过内置的更新机制在线安装Maven插件。本文将详细介绍如何在Eclipse中离线安装Maven插件,以及如何配置Windows环境来确保Maven的正常工作。 首先,我们需要在...
Eclipse是一款广泛使用的Java开发集成环境,而Maven是一个强大的项目管理和构建工具,它通过一个中央仓库...在日常开发中,记得定期更新Maven插件以获取最新的功能和修复,保持与Maven的同步,以确保最佳的开发体验。
通过Maven插件,Eclipse用户可以直接在IDE内部创建、编译、测试、打包和部署Maven项目,极大地提高了开发效率。 安装Maven插件的过程通常分为以下几步: 1. **下载Maven**:首先,你需要从Apache官方网站...
对于开发和发布自定义Maven插件,我们需要遵循Maven插件开发指南。首先创建一个Maven插件项目,包含`pom.xml`文件,指定`maven-plugin`作为打包类型,并声明插件元数据。例如: ```xml <groupId>your.group.id ...
Eclipse作为流行的Java集成开发环境(IDE),通过安装Maven插件,可以让开发者在Eclipse内部方便地进行Maven项目的开发和管理。下面我们将详细介绍如何在Eclipse中安装Maven插件。 首先,我们需要知道为什么要在...
总的来说,自定义Maven插件是提升开发效率、实现个性化需求的重要手段。开发者需要理解Maven的生命周期和插件机制,才能灵活地设计和实现自定义插件。同时,良好的文档和测试也是确保插件质量的关键。
本文将详细讲解如何在Jenkins中安装Git和Maven插件,以便实现版本控制与构建管理。 首先,让我们了解Jenkins插件的作用。Jenkins通过插件扩展其功能,提供对各种工具和技术的支持。Git插件允许Jenkins与Git仓库进行...
** Maven 插件压缩包详解 ** Maven 是一个强大的项目管理工具,...通过以上步骤,你可以在离线环境下有效地使用 Maven 插件,提高开发效率。参考链接中的博客文章提供了更详细的步骤和示例,可以进一步了解如何操作。