上幾篇從應用角度來講Maven,這篇還本着應用的精神繼續講解,Maven最好玩的地方不是單單的爲你管理了jar這麼簡單,而是在他所定義的生命週期和插件下,玩多模塊纔是最有意思的,這篇大概講一下生命週期和插件,下篇講多模塊依賴。
Maven的聲明週期有三套,這裏只說平時用到最核心的一套,也就是默認的聲明週期,有以下幾個重要的過程(其餘忽略):
validate:驗證項目正確性以及所必須信息的完整性。
initialize:初始化構建狀態
generate-sources:產生所有的用來編譯的源代碼
process-sources:處理源代碼
generate-resources:處理項目主資源文件。對src/main/resources目錄的內容進行變量替換等工作後,複製到項目輸出的主classpath目錄中。
process-resources:複製並處理資源文件,至目標目錄,準備打包。
compile:編譯項目的源代碼。
process-test-resources:複製並處理資源文件,至目標測試目錄。
test-compile:編譯測試源代碼。
test:使用合適的單元測試框架運行測試。這些測試代碼不會被打包或部署。
package:接受編譯好的代碼,打包成可發佈的格式,如JAR。
install:將包安裝至本地倉庫,以讓其它項目依賴。
deploy:將最終的包複製到遠程的倉庫,以讓其它開發人員與項目共享。
Maven本身是一個插件框架,因此一系列的動作都要靠插件來完成,想玩Maven,必須對插件靈活運用,比如maven-compiler-plugin是用來編譯的,每一個任務都是需要插件的一個目標(goal)來完成,那maven-compiler-plugin的compile目標就是用來編譯位於src/main/java/目標下的源碼,而testCompile是用來編譯src/test/java目標下的測試源碼。
Maven開發者提供了很多有用的插件,也提供用戶自己開發插件。先說用法,插件有兩種用法,一種是直接運行命令,另一種是和聲明週期綁定,前者如mvnarchetype:generate,表示調用maven-archetype-plugin的generate目標,命令都是帶冒號的;後者的具體用法如下:
那麼如何來寫一個插件呢?其實平時提供的這些插件基本夠用,本人太懶,沒有親自寫,但下面是一位網友寫的內容,通俗易懂,我就拿來主義了。
所有的mojo都繼承自org.apache.maven.plugin.AbstractMojo,我們來建立我們的maven插件工程:
- mvn archetype:create -DgroupId=com.alibaba.maven.plugins -DartifactId=greeting-maven-plugin -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-mojo
跟普通Maven的項目一樣,自己定義groupId和artifactId。我們這裏分別定義groupId爲com.alibaba.maven.plugins和greeting-maven-plugin。
archetypeGroupId和archetypeArtifactId用來定位用哪個maven的工程模板來建立項目。當然我們使用的是maven-archetype-mojo模板來建立插件項目。
- /** @author admin
- * @goal sayHello
- */
- public class HelloWorldMojo extends AbstractMojo{
- @Override
- public void execute() throws MojoExecutionException, MojoFailureException {
- getLog().info("Hello World!");
- }}
Ok,如上所示我們複寫了execute方法,最重要@goal的一個annotation,它定義了這個mojo跟goal一一對應的關係。現在我們運行命令mvninstall把該插件先發布到本地庫。之後我們便可以執行我們的插件了。
插件的運行方式爲:mvngroupID:artifactID:version:goal
按照我們的項目,那麼我們運行插件應該:mvncom.alibaba.maven.plugins:greeting-maven-plugin:1.0-SNAPSHOT:sayHello
看看,我們是不是已經在控制檯看到我們打出的"HelloWorld"文字了。想想,爲什麼mvn eclipse:eclipse的插件運行方式可以這麼簡單。
怎麼減少輸入呢?首先,我們在maven的setting.xml配置文件中,可以找到這樣一個配置項:
- <pluginGroups>
- <pluginGroup>*</pluginGroup>
- </pluginGroups>
如果這裏配置上我們的groupID,如我們的com.alibaba.maven.plugins,那麼groupId的輸入便可省略了。
另外,我們的項目名稱DartifactId如果以${name}-maven-plugin或以maven-${name}-plugin的格式命名,我們便能省去-maven-plugin等信息。
version本來可以省略,maven會找到最新的版本來執行。
那麼省略後的執行命令就可以這樣寫了:mvngreeting:sayHello
Ok,那麼我要運行插件時輸入參數,該怎麼處理呢?如同mvn install -Dmaven.test.skip=true。我們重寫我們的mojo,加入@parameter的annotation。如下
- /**
- * @author admin
- * @goal sayHello
- */
- public class HelloWorldMojo extends AbstractMojo{
- /**
- * @parameter default-value="Somebody" expression="${username}
- */
- private String userName;
- @Override
- public void execute() throws MojoExecutionException, MojoFailureException {
- getLog().info("Hello World!"+userName);
- }}
在install一把,然後運行mvngreeting:sayHello -Dusername=張三。這樣就可以了。
其中一個比較重要的插件tomcat,實現項目的熱部署:
http://stackoverflow.com/questions/13336816/tomcat7-maven-plugin-tomcatmanager-status-code403-reasonphraseforbbiden