Maven:编写Maven组件

一、编写Maven插件步骤 
在这里,我们就一个小的项目案例为大家演示一下如何一步一步编写Maven插件。该案例实现的功能是,统计Maven项目各个源代码目录下面文件的数量,以及它们加起来共多少代码。 
1.创建maven-plugin项目:插件本身也是Maven项目,特殊的地方在于它packaging必须是maven-plugin;使用maven-archetype-plugin快速创建一个Maven项目。 
C:\Users\chengxiang.peng.QUNARSERVERS\MavenSources>mvn archetype:generate 
[INFO] Scanning for projects... 
[INFO] 
[INFO] ------------------------------------------------------------------------ 
[INFO] Building Maven Stub Project (No POM) 1 
[INFO] ------------------------------------------------------------------------ 
[INFO] 
[INFO] >>> maven-archetype-plugin:2.4:generate (default-cli) > generate-sources@ standalone-pom >>> 
[INFO] 
[INFO] <<< maven-archetype-plugin:2.4:generate (default-cli) < generate-sources@ standalone-pom <<< 
[INFO] 
[INFO] --- maven-archetype-plugin:2.4:generate (default-cli) @ standalone-pom --- 
[INFO] Generating project in Interactive mode 
... ...  
1713: remote -> us.fatehi:schemacrawler-archetype-plugin-dbconnector (-) 
1714: remote -> us.fatehi:schemacrawler-archetype-plugin-lint (-) 
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): 876: maven-archetype-plugin 
Choose archetype: 
1: remote -> org.apache.maven.archetypes:maven-archetype-plugin (An archetype which contains a sample Maven plugin.) 
2: remote -> org.apache.maven.archetypes:maven-archetype-plugin-site (An archetype which contains a sample Maven plugin site. This archetype can be layered upon 
 an existing Maven plugin project.) 
Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : 1 
Choose org.apache.maven.archetypes:maven-archetype-plugin version: 
1: 1.0 
2: 1.1 
3: 1.2 
Choose a number: 3: 3 
Define value for property 'groupId': : com.chengxiang.maven 
Define value for property 'artifactId': : maven-plugin 
Define value for property 'version':  1.0-SNAPSHOT: : 
Define value for property 'package':  com.chengxiang.maven: : maven-plugin 
Confirm properties configuration: 
groupId: com.chengxiang.maven 
artifactId: maven-plugin 
version: 1.0-SNAPSHOT 
package: maven-plugin 
 Y: : Y 
[INFO] ---------------------------------------------------------------------------- 
[INFO] Using following parameters for creating project from Archetype: maven-archetype-plugin:1.2 
[INFO] ---------------------------------------------------------------------------- 
[INFO] Parameter: groupId, Value: com.chengxiang.maven 
[INFO] Parameter: artifactId, Value: maven-plugin 
[INFO] Parameter: version, Value: 1.0-SNAPSHOT 
[INFO] Parameter: package, Value: maven-plugin 
[INFO] Parameter: packageInPathFormat, Value: maven-plugin 
[INFO] Parameter: package, Value: maven-plugin 
[INFO] Parameter: version, Value: 1.0-SNAPSHOT 
[INFO] Parameter: groupId, Value: com.chengxiang.maven 
[INFO] Parameter: artifactId, Value: maven-plugin 
[INFO] project created from Archetype in dir: C:\Users\chengxiang.peng.QUNARSERVERS\MavenSources\maven-plugin 
[INFO] ------------------------------------------------------------------------ 
[INFO] BUILD SUCCESS 
[INFO] ------------------------------------------------------------------------ 
[INFO] Total time: 02:31 min 
[INFO] Finished at: 2016-10-16T23:39:06+08:00 
[INFO] Final Memory: 14M/172M 
[INFO] ------------------------------------------------------------------------
2.为插件编写目标、配置点和目标行为,处理相关错误日志:每个插件都包含一个或者多个目标,故必须提供一个或者多个继承AbstractMojo类;可视具体情况提供可配置的参数;根据具体目标实现execute()方法逻辑; 
/** 
 * CountMojo:每个插件的目标类都需要继承AbstractMojo,并实现execute()方法 
 * Created by chengxiang.peng on 2016/10/17. 
 * "@goal":标注来写明自己的目标名称 
 * @goal count 
 */ 
public class CountMojo extends AbstractMojo { 
    //默认统计Java,xml和properties文件 
    private static final String[] INCLUDES_DEFAULT = {"java", "xml", "properties"}; 
 
    /** 
     * "expression":从系统属性读取这几个字段;"@readonly":不允许用户进行配置 
     * 项目基础目录 
     * @parameter expression="${project.basedir}" 
     * @required 
     * @readonly 
     */ 
    private File basedir; 

    /** 
     * 主代码目录 
     * @parameter expression="${project.build.sourceDirectory}" 
     * @required 
     * @readonly 
     */ 
    private File sourceDirectory; 

    /** 
     * 测试代码目录 
     * @parameter expression="${project.build.testSourceDirectory}" 
     * @required 
     * @readonly 
     */ 
    private File testSourceDirectory; 

    /** 
     * 主资源目录 
     * @parameter expression="${project.build.resources}" 
     * @required 
     * @readonly 
     */ 
    private List<Resource> resources; 

    /** 
     * 测试资源目录 
     * @parameter expression="${project.build.testResources}" 
     * @required 
     * @readonly 
     */ 
    private List<Resource> testResources; 

    /** 
     * "@parameter":使用该插件的时候,可以配置该参数 
     * 计算的代码行数的类型范围 
     * @parameter 
     */ 
    private String[] includes; 

    public void execute() throws MojoExecutionException { 
        //如果没有配置类型范围,则使用默认的类型范围 
        if (includes == null || includes.length == 0) { 
            includes = INCLUDES_DEFAULT; 
        } 

        try { 
            //统计主代码目录 
            countDir(sourceDirectory); 
            //统计测试代码目录 
            countDir(testSourceDirectory); 
            //统计主资源目录 
            for (Resource resource : resources) { 
                countDir(new File(resource.getDirectory())); 
            } 

            //统计测试资源目录 
            for (Resource resource : testResources) { 
                countDir(new File(resource.getDirectory())); 
            } 
        } catch (IOException e) { 
            //异常转译,将IO异常转换成Mojo定义的异常抛出 
            throw new MojoExecutionException("Unable to count lines of code.", e); 
        } 
    } 

    /** 
     * 统计指定目录下文件的代码行数 
     * @param dir 统计的指定目录 
     * @throws IOException 不处理IO异常,抛出给外部处理 
     */ 
    private void countDir(File dir) throws IOException { 
        if (!dir.exists()) { 
            return; 
        }  
        //查找目标目录中指定类型的文件集合 
        List<File> collected = new ArrayList<File>(); 
        collectFiles(collected, dir); 
        //统计目标类型文件的代码行数 
        int lines = 0; 
        for (File sourceFile : collected) { 
            lines += countLine(sourceFile); 
        } 
        //输出统计结果:AbstractMojo的getLog()方法返回日志对象,输出Maven日志 
        String path = dir.getAbsolutePath().substring(basedir.getAbsolutePath().length()); 
        getLog().info(path + ": " + lines + " lines of code in " + collected.size() + " files"); 
    } 

    /** 
     * 遍历查找目标目录了中指定类型的文件,并保存在集合中 
     * @param collected 指定类型文件集合 
     * @param file 目标目录 
     */ 
    private void collectFiles(List<File> collected, File file) { 
        if (file.isFile()) { 
            //如果是文件,则判断是否为指定类型 
            for (String include : includes) { 
                if (file.getName().endsWith("." + include)) { 
                    collected.add(file); 
                    break; 
                } 
            } 
        } else { 
            //如果是目录,则遍历子文件或者子目录,递归查找 
            for (File sub : file.listFiles()) { 
                collectFiles(collected, sub); 
            } 
        } 
    } 

    /**
     * 统计指定文件的代码行数 
     * @param file 统计目标文件 
     * @return 代码行数 
     * @throws IOException 不处理IO异常,抛出给外部处理 
     */ 
    private int countLine(File file) throws IOException { 
        BufferedReader reader = new BufferedReader(new FileReader(file)); 
        int line = 0; 
        try { 
            while (reader.ready()) { 
                reader.readLine(); 
                line++; 
            } 
        } finally { 
            reader.close(); 
        }
        return line; 
    } 
}
3.上传和测试插件:适用mvn clean install命令,将编写完成的插件,上传在本地库中,然后在实际运行该插件验证其行为; 
C:\Users\chengxiang.peng.QUNARSERVERS\MavenSources\mavenplugin>mvn clean install 
[INFO] Scanning for projects... 
[INFO] 
[INFO] ------------------------------------------------------------------------ 
[INFO] Building mavenplugin Maven Plugin 1.0-SNAPSHOT 
[INFO] ------------------------------------------------------------------------ 
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ mavenplugin --- 
[INFO] Deleting C:\Users\chengxiang.peng.QUNARSERVERS\MavenSources\mavenplugin\target 
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ mavenplugin --- 
[INFO] Using 'UTF-8' encoding to copy filtered resources. 
[INFO] skip non existing resourceDirectory C:\Users\chengxiang.peng.QUNARSERVERS\MavenSources\mavenplugin\src\main\resources 
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ mavenplugin --- 
[INFO] Changes detected - recompiling the module! 
[INFO] Compiling 1 source file to C:\Users\chengxiang.peng.QUNARSERVERS\MavenSources\mavenplugin\target\classes 
[INFO] 
[INFO] --- maven-plugin-plugin:3.2:descriptor (default-descriptor) @ mavenplugin --- 
[INFO] Using 'UTF-8' encoding to read mojo metadata. 
[INFO] Applying mojo extractor for language: java 
//Maven版本升级,@parameter expression="${property}"写法过时,可升级按照说明更新写法 
[WARNING] mavenplugin.CountMojo#basedir: 
[WARNING]   The syntax 
[WARNING]     @parameter expression="${property}" 
[WARNING]   is deprecated, please use 
[WARNING]     @parameter property="property" 
[WARNING]   instead. 
[WARNING] mavenplugin.CountMojo#resources: 
[WARNING]   The syntax 
[WARNING]     @parameter expression="${property}" 
[WARNING]   is deprecated, please use 
[WARNING]     @parameter property="property" 
[WARNING]   instead. 
[WARNING] mavenplugin.CountMojo#sourceDirectory: 
[WARNING]   The syntax 
[WARNING]     @parameter expression="${property}" 
[WARNING]   is deprecated, please use 
[WARNING]     @parameter property="property" 
[WARNING]   instead. 
[WARNING] mavenplugin.CountMojo#testResources: 
[WARNING]   The syntax 
[WARNING]     @parameter expression="${property}" 
[WARNING]   is deprecated, please use 
[WARNING]     @parameter property="property" 
[WARNING]   instead. 
[WARNING] mavenplugin.CountMojo#testSourceDirectory: 
[WARNING]   The syntax 
[WARNING]     @parameter expression="${property}" 
[WARNING]   is deprecated, please use 
[WARNING]     @parameter property="property" 
[WARNING]   instead. 
[INFO] Mojo extractor for language: java found 1 mojo descriptors. 
[INFO] Applying mojo extractor for language: bsh 
[INFO] Mojo extractor for language: bsh found 0 mojo descriptors. 
[INFO] Applying mojo extractor for language: java-annotations 
[INFO] Mojo extractor for language: java-annotations found 0 mojo descriptors. 
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ mavenplugin --- 
[INFO] Using 'UTF-8' encoding to copy filtered resources. 
[INFO] skip non existing resourceDirectory C:\Users\chengxiang.peng.QUNARSERVERS\MavenSources\mavenplugin\src\test\resources 
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ mavenplugin --- 
[INFO] No sources to compile 
[INFO] 
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ mavenplugin --- 
[INFO] No tests to run. 
[INFO] 
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ mavenplugin --- 
[INFO] Building jar: C:\Users\chengxiang.peng.QUNARSERVERS\MavenSources\mavenplugin\target\mavenplugin-1.0-SNAPSHOT.jar 
[INFO] 
[INFO] --- maven-plugin-plugin:3.2:addPluginArtifactMetadata (default-addPluginArtifactMetadata) @ mavenplugin --- 
[INFO] 
//插件构建完毕后,上传到本地仓库后 
[INFO] --- maven-install-plugin:2.4:install (default-install) @ mavenplugin --- 
[INFO] Installing C:\Users\chengxiang.peng.QUNARSERVERS\MavenSources\mavenplugin\target\mavenplugin-1.0-SNAPSHOT.jar to C:\Users\chengxiang.peng.QUNARSERVERS\.m2\repository\com\chengxiang\mavenplugin\1.0-SNAPSHOT\mavenplugin-1.0-SNAPSHOT.jar 
[INFO] Installing C:\Users\chengxiang.peng.QUNARSERVERS\MavenSources\mavenplugin\pom.xml to C:\Users\chengxiang.peng.QUNARSERVERS\.m2\repository\com\chengxiang\mavenplugin\1.0-SNAPSHOT\mavenplugin-1.0-SNAPSHOT.pom 
[INFO] ------------------------------------------------------------------------ 
[INFO] BUILD SUCCESS 
[INFO] ------------------------------------------------------------------------ 
[INFO] Total time: 3.798 s 
[INFO] Finished at: 2016-10-17T17:54:56+08:00 
[INFO] Final Memory: 20M/171M 
[INFO] ------------------------------------------------------------------------ 
在当前的项目目录下,执行编写插件的目标; 
C:\Users\chengxiang.peng.QUNARSERVERS\MavenSources\mavenplugin>mvn com.chengxiang:mavenplugin:1.0-SNAPSHOT:count 
[INFO] Scanning for projects... 
Downloading: http://svn.corp.qunar.com:8081/nexus/content/groups/public/com/chengxiang/mavenplugin/1.0-SNAPSHOT/maven-metadata.xml 
Downloading: http://l-digging7.wap.cn8.qunar.com:8086/content/repositories/thirdparty/com/chengxiang/mavenplugin/1.0-SNAPSHOT/maven-metadata.xml 
[INFO] 
[INFO] ------------------------------------------------------------------------ 
[INFO] Building mavenplugin Maven Plugin 1.0-SNAPSHOT 
[INFO] ------------------------------------------------------------------------ 
[INFO] 
//插件输出结果 
[INFO] --- mavenplugin:1.0-SNAPSHOT:count (default-cli) @ mavenplugin --- 
[INFO] \src\main\java: 165 lines of code in 1 files 
[INFO] ------------------------------------------------------------------------ 
[INFO] BUILD SUCCESS 
[INFO] ------------------------------------------------------------------------ 
[INFO] Total time: 1.472 s 
[INFO] Finished at: 2016-10-17T18:17:31+08:00 
[INFO] Final Memory: 7M/155M 
[INFO] ------------------------------------------------------------------------

二、Mojo标注

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值