首先,我们可以通过eclipse创建一个Maven插件项目,输入groupId和artifactId之后,在该项目的POM文件中会生成如下内容:
<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>com.juvenxu.mvnbook</groupId> <artifactId>maven-loc-plugin</artifactId> <packaging>maven-plugin</packaging> <version>0.0.1-SNAPSHOT</version> <name>Maven LOC Plugin</name> <url>http://www.juvenxu.com</url> <properties> <maven.version>3.0</maven.version> </properties> <dependencies> <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-plugin-api</artifactId> <version>${maven.version}</version> </dependency> </dependencies> </project>
Maven插件项目的POM有两个特殊的地方:
1、它的packaging必须为maven-plugin,这种特殊的打包类型能够控制Maven为其在生命周期阶段绑定插件处理相关的目标,例如在compile阶段,Maven需要为插件项目构建一个特殊插件描述符文件。
2、从上述代码中可以看到一个artifactId为maven-plugin-api的依赖,该依赖中包含了插件开发所必须得类,例如稍后会看到的AbstractMojo在CountMojo中的应用。
CountMojo代码:
/** * Goal which counts lines of code of a project * * @goal count */ public class CountMojo extends AbstractMojo{ private static final String[] INCLUDES_DEFAULT = {"java", "xml", "properties"}; /** * @parameter expression = "${project.basedir}" * @required * @readonly */ private File basedir; /** * @parameter expression = "${project.build.sourceDirectory}" * @required * @readonly */ private File sourceDirectory; /** * @parameter expression = "${project.testSourceDirectory}" * @required * @readonly */ private File testSourceDirectory; /** * @parameter expression = "${project.resources}" * @required * @readonly */ private List<Resource> resources; /** * @parameter expression = "${project.testResources}" * @required * @readonly */ private List<Resource> testResources; /** * @parameter */ private String[] includes; public void execute() throws MojoExecutionException{ if(includes == null || includes.length -- 0){ includes = INCLUDES_DEFULT; } try{ countDir(sourceDirectory); countDir(testSourceDirectory); for(Resource resource : resources){ countDir(new File(resource.getDirectory())); } for(Resource resource : testSesources){ countDir(new File(resource.getDirectory())); } }atch (IOException e){ throw new MojoExecutionException("Unable to count lines of code.", e); } private void countDir(File file){ // to do somethings ... } } }
首先,每个插件目标类,或者说MOJO,都必须继承AbstractMojo类并实现execute()方法,只有这样Maven才能识别该插件目标,并执行execute()方法中的行为。其次,由于历史原因,上述CountMojo类使用了Java 1.4风格的标注(将标注写在注释中),这里要关注的时@goal,任何一个Mojo都必须使用该标注写明自己的目标名称,有了目标定义之后,我们才能在项目中配置该插件目标,或者在命令行调用之,例如:
$mvn com.juvenxu.mvnbook:maven-loc-plugin:0.0.1-SNAPSHOT:count
创建一个Mojo所必要的工作就是这三项:继承AbstractMojo、实现execute方法、提供@goal标注。
接下来是如何在POM中配置插件(也可以参考签名的文章):
<plugin> <groupId>com.juvenxu.mvnbook</groupId> <artifactId>maven-loc-plugin</artifactId> <version>0.0.1-SNAPSHOT</version> <configuraction> <includes> <include>java</include> <include>sql</include> </includes> </configuraction> </plugin>
如果嫌上面的命令行太长太复杂,可以将该插件的groupId添加在settings.xml中,如:
<settings> <pluginGroups> <pluginGroup>com.juvenxu.mvnbook</pluginGroup> </pluginGroups> </settings>
现在Maven命令行就可以简化成:
$mvn loc:count