maven-自定义插件

#Maven插件基本原理
##一、什么是maven插件
Maven 是一个执行插件的框架,每一个任务实际上是由插件完成的。Maven 插件通常用于:

创建 jar 文件

创建 war 文件

编译代码文件

进行代码单元测试

创建项目文档

创建项目报告

一个插件通常提供了一组目标,可使用以下语法来执行:

mvn [plugin-name]:[goal-name]

例如,一个 Java 项目可以使用 Maven 编译器插件来编译目标,通过运行以下命令编译

mvn compiler:compile

##二、maven插件类型
Maven 提供以下两种类型插件:

类型 描述
构建插件 在生成过程中执行,并在 pom.xml 中的 build元素进行配置
报告插件 在网站生成期间执行,在 pom.xml 中的 reporting 元素进行配置
以下是一些常见的插件列表:

插件 描述

clean 编译后的清理目标,删除目标目录

compiler 编译 Java 源文件

surefile 运行JUnit单元测试,创建测试报告

jar 从当前项目构建 JAR 文件

war 从当前项目构建 WAR 文件

javadoc 产生用于该项目的 Javadoc

antrun 从构建所述的任何阶段运行一组 Ant 任务
##三、maven插件原理

maven通过为某一个项目的生命周期阶段绑定若干个Mojo,然后依次执行Mojo.execute()方法,从而实现特定生命周期应该执行的动作。

例如

Mojo( name = "resources", defaultPhase = LifecyclePhase.PROCESS_RESOURCES, threadSafe = true ) 
public class ResourcesMojo 
 extends AbstractMojo 
 implements Contextualizable 
{ 
 /** 
 下面若干个attribute ,maven 读取pom.xml内的配置信息,这里的attribute对应着pom.xml里的配置,如果在这里声明了,maven在创建Mojo 实例 
 instance的时候,会将这些值注入到instance内,供Mojo instance使用 
 */ 
 /** 
 * The character encoding scheme to be applied when filtering resources. 
 */ 
 @Parameter( property = "encoding", defaultValue = "${project.build.sourceEncoding}" ) 
 protected String encoding; 
 
 /** 
 * The output directory into which to copy the resources. 
 */ 
 @Parameter( defaultValue = "${project.build.outputDirectory}", required = true ) 
 private File outputDirectory; 
 
 /** 
 * The list of resources we want to transfer. 
 */ 
 @Parameter( defaultValue = "${project.resources}", required = true, readonly = true ) 
 private List resources; 
 
 /** 
 * 
 */ 
 @Parameter( defaultValue = "${project}", required = true, readonly = true ) 
 protected MavenProject project; 
 
 /** 
 * The list of additional filter properties files to be used along with System and project 
 * properties, which would be used for the filtering. 
 * 
 
 * See also: {@link ResourcesMojo#filters}. 
 * 
 * @since 2.4 
 */ 
 @Parameter( defaultValue = "${project.build.filters}", readonly = true ) 
 protected List buildFilters; 
 
 /** 
 * The list of extra filter properties files to be used along with System properties, 
 * project properties, and filter properties files specified in the POM build/filters section, 
 * which should be used for the filtering during the current mojo execution. 
 * 
 
 * Normally, these will be configured from a plugin's execution section, to provide a different 
 * set of filters for a particular execution. For instance, starting in Maven 2.2.0, you have the 
 * option of configuring executions with the id's 
default-resources
 and 
 * 
default-testResources
 to supply different configurations for the two 
 * different types of resources. By supplying 
extraFilters
 configurations, you 
 * can separate which filters are used for which type of resource. 
 */ 
 @Parameter 
 protected List filters; 
 
 /** 
 * If false, don't use the filters specified in the build/filters section of the POM when 
 * processing resources in this mojo execution. 
 * 
 
 * See also: {@link ResourcesMojo#buildFilters} and {@link ResourcesMojo#filters} 
 * 
 * @since 2.4 
 */ 
 @Parameter( defaultValue = "true" ) 
 protected boolean useBuildFilters; 
 
 /** 
 * 
 */ 
 @Component( role = MavenResourcesFiltering.class, hint = "default" ) 
 protected MavenResourcesFiltering mavenResourcesFiltering; 
 
 /** 
 * 
 */ 
 @Parameter( defaultValue = "${session}", required = true, readonly = true ) 
 protected MavenSession session; 
 
 /** 
 * Expression preceded with the String won't be interpolated 
 * \${foo} will be replaced with ${foo} 
 * 
 * @since 2.3 
 */ 
 @Parameter( property = "maven.resources.escapeString" ) 
 protected String escapeString; 
 
 /** 
 * Overwrite existing files even if the destination files are newer. 
 * 
 * @since 2.3 
 */ 
 @Parameter( property = "maven.resources.overwrite", defaultValue = "false" ) 
 private boolean overwrite; 
 
 /** 
 * Copy any empty directories included in the Resources. 
 * 
 * @since 2.3 
 */ 
 @Parameter( property = "maven.resources.includeEmptyDirs", defaultValue = "false" ) 
 protected boolean includeEmptyDirs; 
 
 /** 
 * Additional file extensions to not apply filtering (already defined are : jpg, jpeg, gif, bmp, png) 
 * 
 * @since 2.3 
 */ 
 @Parameter 
 protected List nonFilteredFileExtensions; 
 
 /** 
 * Whether to escape backslashes and colons in windows-style paths. 
 * 
 * @since 2.4 
 */ 
 @Parameter( property = "maven.resources.escapeWindowsPaths", defaultValue = "true" ) 
 protected boolean escapeWindowsPaths; 
 
 /** 
 *


 * Set of delimiters for expressions to filter within the resources. These delimiters are specified in the 
 * form 'beginToken*endToken'. If no '*' is given, the delimiter is assumed to be the same for start and end. 
 *


 * So, the default filtering delimiters might be specified as: 
 *


 *

 
 * 
 * ${*} 
 * @ 
 * 
 * 


 *


 * Since the '@' delimiter is the same on both ends, we don't need to specify '@*@' (though we can). 
 *


 * 
 * @since 2.4 
 */ 
 @Parameter 
 protected List delimiters; 
 
 /** 
 * @since 2.4 
 */ 
 @Parameter( defaultValue = "true" ) 
 protected boolean useDefaultDelimiters; 
 
 /** 
 *


 * List of plexus components hint which implements {@link MavenResourcesFiltering#filterResources(MavenResourcesExecution)}. 
 * They will be executed after the resources copying/filtering. 
 *


 * 
 * @since 2.4 
 */ 
 @Parameter 
 private List mavenFilteringHints; 
 
 /** 
 * @since 2.4 
 */ 
 private PlexusContainer plexusContainer; 
 
 /** 
 * @since 2.4 
 */ 
 private List mavenFilteringComponents = new ArrayList(); 
 
 /** 
 * stop searching endToken at the end of line 
 * 
 * @since 2.5 
 */ 
 @Parameter( property = "maven.resources.supportMultiLineFiltering", defaultValue = "false" ) 
 private boolean supportMultiLineFiltering; 
 
 public void contextualize( Context context ) 
 throws ContextException 
 { 
 plexusContainer = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY ); 
 } 
 
 public void execute() 
 throws MojoExecutionException 
 { 
 try 
 { 
 
 if ( StringUtils.isEmpty( encoding ) && isFilteringEnabled( getResources() ) ) 
 { 
 getLog().warn( "File encoding has not been set, using platform encoding " + ReaderFactory.FILE_ENCODING 
 + ", i.e. build is platform dependent!" ); 
 } 
 //获取资源文件过滤器配置 
 List filters = getCombinedFiltersList(); 
 //根据现有配置信息创建Resources处理器对象实例 
 MavenResourcesExecution mavenResourcesExecution = 
 new MavenResourcesExecution( getResources(), getOutputDirectory(), project, encoding, filters, 
 Collections.emptyList(), session ); 
 //windows路径处理 
 mavenResourcesExecution.setEscapeWindowsPaths( escapeWindowsPaths ); 
 
 // never include project build filters in this call, since we've already accounted for the POM build filters 
 // above, in getCombinedFiltersList(). 
 mavenResourcesExecution.setInjectProjectBuildFilters( false ); 
 
 mavenResourcesExecution.setEscapeString( escapeString ); 
 mavenResourcesExecution.setOverwrite( overwrite ); 
 mavenResourcesExecution.setIncludeEmptyDirs( includeEmptyDirs ); 
 mavenResourcesExecution.setSupportMultiLineFiltering( supportMultiLineFiltering ); 
 
 // if these are NOT set, just use the defaults, which are '${*}' and '@'. 
 if ( delimiters != null && !delimiters.isEmpty() ) 
 { 
 LinkedHashSet delims = new LinkedHashSet(); 
 if ( useDefaultDelimiters ) 
 { 
 delims.addAll( mavenResourcesExecution.getDelimiters() ); 
 } 
 
 for ( String delim : delimiters ) 
 { 
 if ( delim == null ) 
 { 
 // FIXME: ${filter:*} could also trigger this condition. Need a better long-term solution. 
 delims.add( "${*}" ); 
 } 
 else 
 { 
 delims.add( delim ); 
 } 
 } 
 
 mavenResourcesExecution.setDelimiters( delims ); 
 } 
 
 if ( nonFilteredFileExtensions != null ) 
 { 
 mavenResourcesExecution.setNonFilteredFileExtensions( nonFilteredFileExtensions ); 
 } 
 mavenResourcesFiltering.filterResources( mavenResourcesExecution ); 
 //执行Resource文件拷贝 
 executeUserFilterComponents( mavenResourcesExecution ); 
 } 
 catch ( MavenFilteringException e ) 
 { 
 throw new MojoExecutionException( e.getMessage(), e ); 
 } 
 } 
 
 /** 
 * @since 2.5 
 */ 
 protected void executeUserFilterComponents( MavenResourcesExecution mavenResourcesExecution ) 
 throws MojoExecutionException, MavenFilteringException 
 { 
 
 if ( mavenFilteringHints != null ) 
 { 
 for ( Iterator ite = mavenFilteringHints.iterator(); ite.hasNext(); ) 
 { 
 String hint = (String) ite.next(); 
 try 
 { 
 mavenFilteringComponents.add( 
 (MavenResourcesFiltering) plexusContainer.lookup( MavenResourcesFiltering.class.getName(), 
 hint ) ); 
 } 
 catch ( ComponentLookupException e ) 
 { 
 throw new MojoExecutionException( e.getMessage(), e ); 
 } 
 } 
 } 
 else 
 { 
 getLog().debug( "no use filter components" ); 
 } 
 
 if ( mavenFilteringComponents != null && !mavenFilteringComponents.isEmpty() ) 
 { 
 getLog().debug( "execute user filters" ); 
 for ( MavenResourcesFiltering filter : mavenFilteringComponents ) 
 { 
 filter.filterResources( mavenResourcesExecution ); 
 } 
 } 
 } 
 
 protected List getCombinedFiltersList() 
 { 
 if ( filters == null || filters.isEmpty() ) 
 { 
 return useBuildFilters ? buildFilters : null; 
 } 
 else 
 { 
 List result = new ArrayList(); 
 
 if ( useBuildFilters && buildFilters != null && !buildFilters.isEmpty() ) 
 { 
 result.addAll( buildFilters ); 
 } 
 
 result.addAll( filters ); 
 
 return result; 
 } 
 } 
 
 /** 
 * Determines whether filtering has been enabled for any resource. 
 * 
 * @param resources The set of resources to check for filtering, may be 
null
. 
 * @return 
true
 if at least one resource uses filtering, 
false
 otherwise. 
 */ 
 private boolean isFilteringEnabled( Collection resources ) 
 { 
 if ( resources != null ) 
 { 
 for ( Resource resource : resources ) 
 { 
 if ( resource.isFiltering() ) 
 { 
 return true; 
 } 
 } 
 } 
 return false; 
 } 
}

上面只是介绍了Maven生命周期阶段绑定执行代码的基本模式,由于maven的生命周期众多,并且每个生命周期内有可能绑定多个Mojo,如果使用上述的模式简单关联的话,会显得结构组织很乱。

maven会根据Mojo功能的划分,将具有相似功能的Mojo放到一个插件中。并且某一个特定的Mojo能实现的功能称为 goal,即目标,表明该Mojo能实现什么目标。

##四、绑定
创建项目的源码包, maven-source-plugin插件的jar-no-fork目标能够将项目的主代码打包成jar文件, 可以将其绑定到verify阶段上:

org.apache.maven.plugins
 maven-source-plugin
 3.0.0
 
 
 attach-sources
 verify
 
 jar-no-fork
 
 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值