创建Maven插件工程
通过IDEA创建工程,选择maven-archetype-mojo
模板,artifactId
命名时采用-maven-plugin
结尾
此时pom文件中仅有maven-plugin-api
依赖,再添加maven-plugin-annotations
依赖,是代码支持maven注解
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>young-test</groupId>
<artifactId>young-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>maven-plugin</packaging>
<name>young-test-maven-plugin</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4.3</version>
</plugin>
</plugins>
</build>
</project>
之后,创建一个对象,继承AbstractMojo
类,重写execute()方法,这个方法就是maven插件的执行方法,同时在类上增加@Mojo注解
@Mojo(name = "test",defaultPhase = LifecyclePhase.CLEAN)
public class MyPlugin extends AbstractMojo {
@Parameter(property = "path")
private String path;
public void execute() {
System.out.println("self plugin begin");
System.out.println(path);
System.out.println("self plugin end");
}
}
Mojo注解
/**
* 此注释会将类标记为 Mojo(即 Maven 插件中的目标)
* This annotation will mark your class as a Mojo (ie. goal in a Maven plugin).
*
* @author Olivier Lamy
* @since 3.0
*/
@Documented
@Retention( RetentionPolicy.CLASS )
@Target( ElementType.TYPE )
@Inherited
public @interface Mojo
{
/**
* goal name (required).唯一必须声明的标注,当用户命令行调用或在pom中配置插件是,需使用该目标名称
* 如执行命令 my:test 中的test或者下面xml中的goal
<executions>
<execution>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
* @return the goal name
*/
String name();
/**默认将该目标绑定至default声明周期的某个阶段,这样在配置使用插件目标时,就无需声明phase,如maven-surefire-plugin的test目标带有@phase tes标注
* default phase to bind your mojo.
* @return the default phase
*/
LifecyclePhase defaultPhase() default LifecyclePhase.NONE;
/**在运行mojo之前必须解析所有指定范围的依赖,如maven-surefire-plugin的test目标带有requiresDependencyResolution test标注,表示执行测试前,所有测试范围的依赖必须得到解析
* the required dependency resolution scope.
* @return the required dependency resolution scope
*/
ResolutionScope requiresDependencyResolution() default ResolutionScope.NONE;
/**
* the required dependency collection scope.
* @return the required dependency collection scope
*/
ResolutionScope requiresDependencyCollection() default ResolutionScope.NONE;
/**
* your Mojo instantiation strategy. (Only <code>per-lookup</code> and <code>singleton</code> are supported)
* @return the instantiation strategy
*/
InstantiationStrategy instantiationStrategy() default InstantiationStrategy.PER_LOOKUP;
/**
* execution strategy: <code>once-per-session</code> or <code>always</code>.
* @return <code>once-per-session</code> or <code>always</code>
*/
String executionStrategy() default "once-per-session";
/**该目标是否必须在一个maven项目中运行(如测试插件用于测试其他项目),默认为true。大部分插件目标需依赖一个项目才能运行,但是,maven-help-plugin的system目标例外,它用来显示系统属性和环境变量信息,无需实际项目。
* does your mojo requires a project to be executed?
* @return requires a project
*/
boolean requiresProject() default true;
/**是否要求项目报告已经生成,默认为false
* does your mojo requires a reporting context to be executed?
* @return requires a reporting context
*/
boolean requiresReports() default false;
/**当mojo在多模块项目上运行时,该标注表示目标只会在顶层模块运行。
* if the Mojo uses the Maven project and its child modules.
* @return uses the Maven project and its child modules
*/
boolean aggregator() default false;
/**为true时,该目标就只能通过命令行直接调用。默认为false
* can this Mojo be invoked directly only?
* @return invoked directly only
*/
boolean requiresDirectInvocation() default false;
/**是否要求maven必须是在线状态,默认值为false
* does this Mojo need to be online to be executed?
* @return need to be online
*/
boolean requiresOnline() default false;
boolean inheritByDefault() default true;
/**
* own configurator class.
* @return own configurator class
*/
String configurator() default "";
/**
* is your mojo thread safe (since Maven 3.x)?
* @return is thread safe
*/
boolean threadSafe() default false;
}
Parameter注解
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Used to configure your Mojo parameters to be injected by
* <a href="/ref/current/maven-core/apidocs/org/apache/maven/plugin/MavenPluginManager.html">
* <code>MavenPluginManager.getConfiguredMojo(...)</code></a>.
*
* @author Olivier Lamy
* @since 3.0
*/
@Documented
@Retention( RetentionPolicy.CLASS )
@Target( { ElementType.FIELD } )
@Inherited
public @interface Parameter
{
/**
* alias supported to get parameter value.
* @return the alias
*/
String alias() default "";
/**
* 配置了property参数,才能从命令行的-D中获取对应的变量值
* Property to use to retrieve a value. Can come from <code>-D</code> execution, setting properties or pom properties.
* @return property name
*/
String property() default "";
/**
* parameter default value, eventually containing <code>${...}</code> expressions which will be interpreted at
* inject time: see
* <a href="/ref/current/maven-core/apidocs/org/apache/maven/plugin/PluginParameterExpressionEvaluator.html">
* PluginParameterExpressionEvaluator</a>.
* @return the default value
*/
String defaultValue() default "";
/**
* 参数是否必填,如果为true,没有配置时会报错
* is the parameter required?
* @return <code>true</code> if the Mojo should fail when the parameter cannot be injected
*/
boolean required() default false;
/**
* 是否只读属性,是的话则该属性不允许被配置
* Specifies that this parameter cannot be configured directly by the user (as in the case of POM-specified
* configuration). This is useful when you want to force the user to use common POM elements rather than plugin
* configurations, as in the case where you want to use the artifact's final name as a parameter. In this case, you
* want the user to modify <code><build><finalName/></build></code> rather than specifying a value
* for finalName directly in the plugin configuration section. It is also useful to ensure that - for example - a
* List-typed parameter which expects items of type Artifact doesn't get a List full of Strings.
*
* @return <code>true</code> if the user should not be allowed to configure the parameter directly
*/
boolean readonly() default false;
}
打包编译
代码编写完之后,执行mvn install 或者mvn depoly即可
执行插件
pom文件
<build>
<plugins>
<plugin>
<groupId>young-test</groupId>
<artifactId>young-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<executions>
<execution>
<goals>
<!-- 执行目标 -->
<goal>test</goal>
</goals>
<!-- 执行这个目标所在的生命周期,配置了注解的defaultPhase则可以不写 -->
<phase>clean</phase>
</execution>
</executions>
<configuration>
<path>2134</path>
</configuration>
</plugin>
</plugins>
</build>
此时我们执行mvn clean
命令可以看到如下日志,表示我们的自定义插件已经执行了,并且打印出了配置的值2134
[INFO]
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ credit-bdp-stream-server ---
[INFO]
[INFO] --- flatten-maven-plugin:1.2.5:clean (flatten.clean) @ credit-bdp-stream-server ---
[INFO]
[INFO] --- young-maven-plugin:1.0-SNAPSHOT:test (default) @ credit-bdp-stream-server ---
self plugin begin
2134
self plugin end
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.783 s
注意
在pom文件中声明了参数的情况下,使用-D参数是无法覆盖的
例如,执行 mvn clean -Dpath=5678
,从日志上可以看出,打印的值还是2134,如果将<path>2134</path>
中的值去掉,再执行 mvn clean -Dpath=5678
,此时日志中的值就被改为了命令行中的值,也就是说,只有参数没有在xml中初始化的时候,命令-D参数才有效。
使用命令行
如果使用命令行直接调用查询,那么在pom文件中不能申明插件,否则会执行两次该插件
直接调用插件的格式为 groupId:artifactId:version:goal
,即young-test:young-maven-plugin:1.0-SNAPSHOT:test
,参数使用-D传输
这种写法十分繁琐,如果我们像执行官方插件那样执行我们的插件mvn young:test -Dpath=9527
,控制台会提示错误
No plugin found for prefix 'young' in the current project and in the plugin groups [org.apache.maven.plugins, org.codehaus.mojo] available from the repositories [local (H:\JDP\Maven\repository), nexus-releases (http://localhost:8081/nexus/content/groups/public)] -> [Help 1]
这说明,maven模式回去找groupId
为org.apache.maven.plugins
和org.codehaus.mojo
的插件,此时需要在settings.xml
文件中找到pluginGroups
标签,同时添加一个pluginGroup
,值为我们自己的groupId
即可,添加完之后保存settings.xml,此时再执行mvn young:test -Dpath=9527
,即可在控制台看到我们插件已经被执行了。
注意
插件命名未使用-maven-plugin
结尾时,无法使用短命令执行
maven内置属性
1、maven属性
内置属性(maven预定义,用户可以直接使用的)
主要有两个常用内置属性——
${basedir}表示项目根目录,即包含pom.xml文件的目录;
${version}表示项目版本。
project.basedir同project.basedir同{basedir};
2、POM属性(使用pom属性可以引用到pom.xml文件对应的元素的值)
${project.build.sourceDirectory}:项目的主源码目录,默认为src/main/java/.
${project.build.testSourceDirectory}:项目的测试源码目录,默认为/src/test/java/.
${project.build.directory}:项目构建输出目录,默认为target/.
${project.outputDirectory}:项目主代码编译输出目录,默认为target/classes/.
${project.testOutputDirectory}:项目测试代码编译输出目录,默认为target/testclasses/.
${project.groupId}:项目的groupId.
${project.artifactId}:项目的artifactId.
${project.version}:项目的version,于${version}等价
${project.build.finalName}:项目打包输出文件的名称,默认 为${project.artifactId}${project.version}自定义属性(在pom.xml文件的<properties>标签下定义的maven属性)
<project>
<properties>
<my.pro>proname</my.pro>
</properties>
</project>
在其他地方就可以使用该自定义的属性了:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${my.pro}</version>
</dependency>
setting.xml文件属性(与pom属性同理,用户可以用以settings.开头的属性引用setting.xml文件的XML元素值)
${settings.localRepository}表示本地仓库的地址
java系统属性(所有的java系统属性都可以用env,开头的maven属性引用)
使用mvn help:system命令可查看所有环境变量;
${env.JAVA_HOME}表示JAVA_HOME环境变量的值;
参考:
https://www.cnblogs.com/oscar1987121/p/10959083.html
https://blog.csdn.net/weixin_41358004/article/details/107399647
https://www.cnblogs.com/cxyyh/p/10847620.html
https://www.cnblogs.com/feiyujun/p/12122159.html