maven 插件源码

359 阅读2分钟

maven-plugin-api

<dependency>  
    <groupId>org.apache.maven</groupId>  
    <artifactId>maven-plugin-api</artifactId>  
    <version>${mavenVersion}</version>  
    <scope>provided</scope>  
</dependency>

maven-plugin-annotations

概念:maven插件注解 包含:

  • @Mojo:
    • 将class作为mojo对象
  • @Component:
    • 通过MavenPluginManager.getConfiguredMojo(…)来配置Plexus组件的注入。
  • @Execute:
    • 被用于mojo生命周期
  • @Parameter:
    • 用来配置被MavenPluginManager.getConfiguredMojo(…)注入的Mojo参数
  • ResolutionScope:enum:
    • 在mojo执行之前可用的依赖项解析范围。重要提示:此枚举的id值对应于org.apache.maven.artifact.Artifact类的常量,必须保持同步。
  • LifecyclePhase:enum:
    • 生命周期
  • InstantiationStrategy:enum:
    • 实例化策略
<!-- dependencies to annotations -->  
<dependency>  
    <groupId>org.apache.maven.plugin-tools</groupId>  
    <artifactId>maven-plugin-annotations</artifactId>  
    <scope>provided</scope>  
</dependency>

maven-clean-plugin

核心:CleanMojo 尝试清理项目中 build 时生成的目录

image.png

  • 默认会清理四个目录的内容,其他目录需要通过 filesets 进行指定
    • project.build.directory
    • project.build.outputDirectory
    • project.build.testOutputDirectory
    • project.reporting.outputDirectory
  • filesets 结构
 <filesets>
    <fileset>
      <directory>src/main/generated</directory>
      <followSymlinks>false</followSymlinks>
      <useDefaultExcludes>true</useDefaultExcludes>
      <includes>
        <include>*.java</include>
      </includes>
      <excludes>
        <exclude>Template*</exclude>
      </excludes>
    </fileset>
  </filesets>
  • 删除目录的顺序:
    • (source) directory
    • output directory
    • test directory
    • report directory
    • 其他新增file-sets目录
public void execute() throws MojoExecutionException {  
    if (skip) {  
        // 不清理  
        getLog().info("Clean is skipped.");  
        return;  
    }  

    String multiModuleProjectDirectory =  
    session != null ? session.getSystemProperties().getProperty("maven.multiModuleProjectDirectory") : null;  
    // 
    File fastDir;  
    if (fast && this.fastDir != null) {  
        fastDir = this.fastDir;  
    } else if (fast && multiModuleProjectDirectory != null) {  
        fastDir = new File(multiModuleProjectDirectory, "target/.clean");  
    } else {  
        fastDir = null;  
        if (fast) {  
            getLog().warn("Fast clean requires maven 3.3.1 or newer, "  
                    + "or an explicit directory to be specified with the 'fastDir' configuration of "  
                    + "this plugin, or the 'maven.clean.fastDir' user property to be set.");  
        }  
    }  
    if (fast  
        && !FAST_MODE_BACKGROUND.equals(fastMode)  
        && !FAST_MODE_AT_END.equals(fastMode)  
        && !FAST_MODE_DEFER.equals(fastMode)) {  
        throw new IllegalArgumentException("Illegal value '" + fastMode + "' for fastMode. Allowed values are '"  
            + FAST_MODE_BACKGROUND + "', '" + FAST_MODE_AT_END + "' and '" + FAST_MODE_DEFER + "'.");  
    }  

    // 具体清理操作  
    Cleaner cleaner = new Cleaner(session, getLog(), isVerbose(), fastDir, fastMode);  

    try {  
        // 清理默认目录  
        for (File directoryItem : getDirectories()) {  
            if (directoryItem != null) {  
                cleaner.delete(directoryItem, null, followSymLinks, failOnError, retryOnError);  
            }  
        }  

        // 清理新增的fileset目录  
        if (filesets != null) {  
            for (Fileset fileset : filesets) {  
                if (fileset.getDirectory() == null) {  
                throw new MojoExecutionException("Missing base directory for " + fileset);  
                }  
                GlobSelector selector = new GlobSelector(  
                    fileset.getIncludes(), fileset.getExcludes(), fileset.isUseDefaultExcludes());  
                cleaner.delete(  
                    fileset.getDirectory(), selector, fileset.isFollowSymlinks(), failOnError, retryOnError);  
            }  
        }  
    } catch (IOException e) {  
        throw new MojoExecutionException("Failed to clean project: " + e.getMessage(), e);  
    }  
}

快速删除

  • 创建临时目录,将要删除的目录内容 move 到临时目录后,通过后台线程删除临时目录的内容
  • 快速删除失败后,会继续采用普通删除进行目录内容的删除操作

普通删除

  • 默认失败重试,可以通过maven.clean.retryOnError进行修改。失败尝试情况下会间隔 {50ms,250ms,750ms} 最多尝试3次