maven插件开发

大多数计算机语言的学习都是从Hello World开始,我们通过创建一个在控制台打印Hello World字符串的maven插件来学习如何开发一个自定义maven插件。

 

快速开发第一个插件

1,创建一个maven-plugin目录,并进入此目录。

 

2,运行命令:

 

mvn archetype:create -DgroupId=com.ailbaba.maven -DartifactId=maven-hello-plugin -DarchetypeArtifactId=maven-archetype-mojo

可以看到新建一个工程,其pom.xml:

 

<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.alibaba.maven</groupId>

  <artifactId>maven-hello-plugin</artifactId>

  <packaging>maven-plugin</packaging>

  <version>1.0-SNAPSHOT</version>

  <name>maven-hello-plugin Maven Mojo</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>junit</groupId>

      <artifactId>junit</artifactId>

      <version>3.8.1</version>

      <scope>test</scope>

    </dependency>

  </dependencies>

</project>

3,进入maven-hello-plugin目录,运行命令:mvn eclipse:eclipse构建eclipse工程。

 

4,通过eclipse import工程,删除包下面自动生成的java文件,新建HelloWorldMojo.java,HelloWorldMojo.java的内容如下:

 

package com.alibaba.maven;

 

import org.apache.maven.plugin.AbstractMojo;

import org.apache.maven.plugin.MojoExecutionException;

 

/**

 * @goal helloworld

 */

 

public class HelloWorldMojo extends AbstractMojo {

 

    /**

     * @parameter expression="${helloworld.words}" default-value="Hello World!"

     */

 

    private String words;

 

    public void execute() throws MojoExecutionException {

 

        getLog().info(words);

 

    }

 

}

5, 文件编写完成后回到cmd命令行,在项目的pom文件目录处运行install命令将插件安装到本地repository:mvn clean install

6, 安装成功后继续运行如下命令查看插件的运行情况:

 

运行:

 

mvn com.alibaba.maven:maven-hello-plugin:1.0-SNAPSHOT:helloworld

,可以看到控制台看到输出:"Hello World!";这个输出是插件的默认参数:

 

default-value="Hello World!"

运行

 

mvn com.alibaba.maven:maven-hello-plugin:1.0-SNAPSHOT:helloworld -Dhelloworld.words="welcome!"

可以在控制台看到输出:"welcome!";这个在命令中明确指定插件的参数,因此输出的是指定的参数"welcome!"。

 

关键点

1.maven的参数注入

maven默认使用的自行开发的Plexus,Plexus使用javadoc来管理依赖注入,可以看到上面的@goal,@parameter都是通过这种方式注入,现在看起来非常原始,不过maven3将迁移到guice.

 

2.MOJO

maven是由生命周期和goal完成任务的,比如maven install实际上包换了多种goal.插件中的每个任务goal称作一个 Mojo(Maven plain Old Java Object)。项目中每一个Mojo都要实现org.apache.maven.plugin.Mojo接口,上面的插件示例的Mojo通过扩展org.apache.maven.plugin.AbstractMojo类实现了该接口。Mojo提供如下的方法:

 

void setLog( org.apache.maven.monitor.logging.Log log)

当Maven加载并运行Mojo的时候,它会调用setLog()方法,为Mojo实例提供正确的日志目标。

 

Mojo接口只关心两件事情:目标运行结果的日志记录,以及运行一个目标。当编写自定义插件的时候,需要扩展AbstractMojo。 AbstractMojo处理setLog()和getLog()的实现,并包含一个抽象的execute()方法。在扩展AbstractMojo的时候,你所需要做的只是实现execute()方法。

 

公司maven-autoconfig-plugin探究

在你的本地仓库会有maven autoconfig插件的代码,svn地址:http://svn.alibaba-inc.com/repos/ali_platform/maven/plugins/maven-autoconf-plugin/trunk,可以看一下核心类AutoconfMojo,其实里面非常简单:

 

/**

 * Autoconf Mojo, eg: mvn autoconf:autoconf

 * 

 * @goal autoconf

 * @requiresProject false

 * 

 * @author shawn.qianx

 * @author hongyuan.zhouhy

 * @author william.liangf

 */

public class AutoconfMojo extends AbstractMojo {

 

    /**

     * directory or jar/war/zip archive path, separate by comma, default is current directory.

     * 

     * @parameter expression="${path}"

     */

    private String path;

 

 

    public void execute() throws MojoExecutionException, MojoFailureException {

        getLog().info("Execute autoconf:autoconf.");

        WarConfigRuntimeImpl runtime = new WarConfigRuntimeImpl(System.in, System.out, System.err, charset);

        if(path != null && path.trim().length() > 0){

            runtime.setDests(path.split(","));

        } else {

            runtime.setDests(new String[] {"."});

        }

        if (charset == null) {

            charset = ConfigConstant.DEFAULT_CHARSET;

        }

        if (encoding == null) {

            encoding = ConfigConstant.DEFAULT_CHARSET;

        }

        if (interactive) {

            getLog().info("Turn on interactive mode.");

            runtime.setInteractiveMode(ConfigConstant.INTERACTIVE_ON);

        }

        if (gui) {

            runtime.setGuiMode();

        }

        if (verbose) {

            runtime.setVerbose();

        }

        if(properties != null && properties.trim().length() > 0){

            getLog().info("Customized user properties:" + properties + " using encoding:" + charset);

            runtime.setUserPropertiesFile(properties, charset);

        }

        if (userProp != null && userProp.trim().length() > 0) {

            getLog().info("Customized user properties:" + userProp + " using encoding:" + encoding);

            runtime.setUserPropertiesFile(userProp, encoding);

        }

        if (sharedProperties != null && sharedProperties.length() > 0) {

            getLog().info("Customized shared properties: " + descriptors);

            runtime.setSharedPropertiesFiles(sharedProperties.split(","), sharedPropertiesName, charset);

        }

        if ((descriptors != null && descriptors.length() > 0) 

                || (excludeDescriptors != null && excludeDescriptors.length() > 0)) {

            String[] includes;

            String[] excludes;

            PatternSet patterns = runtime.getDescriptorPatterns();

            if (descriptors == null || descriptors.length() == 0) {

                try {

                    includes = patterns.getIncludes();

                } catch (NullPointerException npe) {

                    includes = new String[0];

                }

            } else {

                getLog().info("Customized include descriptors: " + descriptors);

                includes = descriptors.split(",");

            }

            if (excludeDescriptors == null || excludeDescriptors.length() == 0) {

                try {

                    excludes = patterns.getExcludes();

                } catch (NullPointerException npe) {

                    excludes = new String[0];

                }

            } else {

                getLog().info("Customized exclude descriptors: " + excludeDescriptors);

                excludes = excludeDescriptors.split(",");

            }

            runtime.setDescriptorPatterns(includes, excludes);

        }

        if ((packages != null && packages.length() > 0) 

                || (excludePackages != null && excludePackages.length() > 0)) {

            String[] includes;

            String[] excludes;

            PatternSet patterns = runtime.getPackagePatterns();

            if (packages == null || packages.length() == 0) {

                try {

                    includes = patterns.getIncludes();

                } catch (NullPointerException npe) {

                    includes = new String[0];

                }

            } else {

                getLog().info("Customized include packages: " + descriptors);

                includes = packages.split(",");

            }

            if (excludePackages == null || excludePackages.length() == 0) {

                try {

                    excludes = patterns.getExcludes();

                } catch (NullPointerException npe) {

                    excludes = new String[0];

                }

            } else {

                getLog().info("Customized exclude packages: " + excludeDescriptors);

                excludes = excludePackages.split(",");

            }

            runtime.setPackagePatterns(includes, excludes);

        }

        try {

            runtime.start();

        } catch (Exception e) {

            runtime.error(e);

            throw new MojoExecutionException("autoconf execution error", e);

        }

    }

 

}

小结

开发一个maven插件就是开发一个mojo,然后这样使用它们:maven xx:xx 。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值