1,建立一個maven plugin項目 html
mvn archetype:generate \ -DgroupId=sample.plugin \ -DartifactId=hello-maven-plugin \ -DarchetypeGroupId=org.apache.maven.archetypes \ -DarchetypeArtifactId=maven-archetype-plugin
其中 archetypeGroupId 是固定的,其餘的 groupId .... 你本身配置 java
2,配置你的plugin的快捷方式 apache
能夠看到1中生成的maven plugin 項目 也算是個標準的maven項目,找到pom.xml中的下方所示,配置 maven
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.2</version>
<configuration>
<goalPrefix>sun</goalPrefix>
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
</configuration> ide
goalPrefix這一項,這個是調用插件的快捷方式,若是不配置這個你調用某個plugin就是 ui
mvn groupId:artifactId:version:goal
而若是像我這裏設置的則是(sun就是個人調用前綴了) url
mvn sun:goal
3,Mojo 類的配置。涉及2中屢次出現的goal,goal就是某個具體執行目標了,通常來講一個插件通常能夠執行多個功能。 spa
package sample.plugin; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.Mojo; @Mojo( name = "sayhi",requiresProject=true,requiresDependencyResolution=ResolutionScope.RUNTIME) @Execute(phase = LifecyclePhase.COMPILE) public class GreetingMojo extends AbstractMojo{ @Parameter(defaultValue = "8080",property ="port",required = false) private int port; public void execute() throws MojoExecutionException { getLog().info( "Hello, world." ); } }
@Parameter註解是給 成員變量注入 配置值,對應的在項目中要引入使用此plugin時配置以下 插件
<plugin>
<groupId>xxx</groupId>
<artifactId>xxx</artifactId>
<configuration>
<port>9090</port>
</configuration>
</plugin>
這樣配置信息就注入了Mojo對象內了。
code
這個註解 @Mojo(name="sayhi"),sayhi就是一個goal。這樣的類能夠有多個,固然是不一樣的goal。
那麼若是我
mvn sun:sayhi則 該類的execute方法就會被執行。maven plugin的工做原理就是如此了。你能夠動手開始你的第一個maven plugin的開發了。下面講一些其中可能會遇到的坑。
4,plugin classLoader
頗有可能你的插件是要做用於引用這個插件的那個maven項目的。可是plugin是被叫作plugin classLoader加載的,而這個load是沒有引用方project的classPath的,也就是說在plugin代碼中沒法加載引用方project的類和對象。
參考:http://maven.apache.org/guides/mini/guide-maven-classloading.html
可是這樣也不是說徹底沒有辦法,咱們能夠經過給Mojo對象添加一個成員變量MavenProject,該對象能夠獲取 註解@Mojo(requiresDependencyResolution=ResolutionScope.RUNTIME)中指定的classPath路徑,經過建立本身的classLoader來加載目標class就好了。
@Parameter(defaultValue = "${project}",required = true) private MavenProject project; private ClassLoader projectLoader; private ClassLoader getClassLoader() throws MojoExecutionException{ if(projectLoader==null){ try{ List<String> classpathElements = project.getCompileClasspathElements(); System.out.println(classpathElements); classpathElements.add(project.getBuild().getOutputDirectory() ); System.out.println(project.getBuild().getOutputDirectory()); classpathElements.add(project.getBuild().getTestOutputDirectory() ); System.out.println(classpathElements); URL urls[] = new URL[classpathElements.size()]; for ( int i = 0; i < classpathElements.size(); ++i ) { urls[i] = new File( (String) classpathElements.get( i ) ).toURI().toURL(); } projectLoader=new URLClassLoader(urls, getClass().getClassLoader() ); } catch (Exception e){ throw new MojoExecutionException("Couldn't create a project classloader.", e); } } return projectLoader; }
接下來你要執行 目標 maven plugin goal時仍然會發現找不到classPath那是由於項目尚未編譯,而你但願你的plugin是自動執行某個maven生命週期後執行,好比在編譯後執行,那麼就須要 @Execute(phase = LifecyclePhase.COMPILE)
5 ,上傳你的插件到本身的私服後,在設置maven的倉庫爲本身私服後,就能夠下載使用本身插件了