深入理解maven及應用(一):生命週期和外掛

chaofanwei發表於2014-07-02

        在專案裡用了快一年的maven了,最近突然發現maven專案在eclipse中build時非常慢,因為經常用clean install命令來build專案,也沒有管那麼多,但最近實在受不了烏龜一樣的build速度,於是下定決心再看看《maven實戰》吧,
        對於我來說,maven最主要的作用有兩個方面,一個是對jar包的依賴解決功能,自己管理jar包,另一個功能就是專案的構建,打包部署。現在我覺得最重要的還是maven的生命週期和外掛機制,下面就來總結一下吧。

    參考url:http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html


1、三套生命週期


     對於maven的生命週期來說,共有三個相互獨立的生命週期,分別是clean、default、site。clean生命週期目的是清理專案,default生命週期目的是構建專案,而site生命週期目的是建立專案站點。
     每個生命週期分別包含一些階段,這些階段是有順序的,並且後面的階段依賴於前面的階段。如clean生命週期包含pre-clean、clean和post-clean三個階段,如果執行clean階段,則會先執行pre-clean階段。
     較之於生命週期階段有前後依賴關係,三套生命週期本身是相互獨立的,使用者可以僅呼叫clean生命週期的某個階段,也可以不執行clean週期,而直接執行default生命週期的某幾個階段。


2、clean生命週期


     clean生命週期包含三個階段,主要負責清理專案,如下:

pre-clean executes processes needed prior to the actual project cleaning
clean remove all files generated by the previous build
post-clean executes processes needed to finalize the project cleaning


3、default生命週期


    default生命週期定義了真正構建時所需要執行的所有步驟,包含的階段如下:

validate validate the project is correct and all necessary information is available.
initialize initialize build state, e.g. set properties or create directories.
generate-sources generate any source code for inclusion in compilation.
process-sources process the source code, for example to filter any values.
generate-resources generate resources for inclusion in the package.
process-resources copy and process the resources into the destination directory, ready for packaging.
compile compile the source code of the project.
process-classes post-process the generated files from compilation, for example to do bytecode enhancement on Java classes.
generate-test-sources generate any test source code for inclusion in compilation.
process-test-sources process the test source code, for example to filter any values.
generate-test-resources create resources for testing.
process-test-resources copy and process the resources into the test destination directory.
test-compile compile the test source code into the test destination directory
process-test-classes post-process the generated files from test compilation, for example to do bytecode enhancement on Java classes. For Maven 2.0.5 and above.
test run tests using a suitable unit testing framework. These tests should not require the code be packaged or deployed.
prepare-package perform any operations necessary to prepare a package before the actual packaging. This often results in an unpacked, processed version of the package. (Maven 2.1 and above)
package take the compiled code and package it in its distributable format, such as a JAR.
pre-integration-test perform actions required before integration tests are executed. This may involve things such as setting up the required environment.
integration-test process and deploy the package if necessary into an environment where integration tests can be run.
post-integration-test perform actions required after integration tests have been executed. This may including cleaning up the environment.
verify run any checks to verify the package is valid and meets quality criteria.
install install the package into the local repository, for use as a dependency in other projects locally.
deploy done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects.

 

4、site生命週期


     siet生命週期的目的是建立和釋出專案站點,maven能夠基於POM所包含的資訊,自動生成一個友好的站點,方便團隊交流和釋出專案資訊,包含的階段如下:

    

pre-site executes processes needed prior to the actual project site generation
site generates the project's site documentation
post-site executes processes needed to finalize the site generation, and to prepare for site deployment
site-deploy deploys the generated site documentation to the specified web server

5、命令列與生命週期

     從命令列執行maven任務的最主要方式就是呼叫maven的生命週期階段。需要注意的是,各個生命週期是相互獨立的,而一個生命週期的階段是有前後依賴關係的。例子如下:
     1、$mvn clean :該命令呼叫clean生命週期的clean階段。實際執行的階段為clean生命週期的pre-clean和clean階段。
     2、$mvn test:該命令呼叫default生命週期的test階段。實際呼叫的是default生命週期的validate、initialize等,直到test的所有階段。
     3、$mvn clean install:該命令調換用clean生命週期的clean階段和default生命週期的instal階段。

6、外掛目標

      maven的核心僅僅定義了抽象的生命週期,具體的任務是交由外掛完成的,外掛以獨立的形式存在。
     對於外掛本身,為了能夠複用程式碼,它往往能夠完成多個任務。如maven-dependency-plugin有十多個目標,每個目標對應了一個功能,如 dependency:analyze、 dependency:tree和dependency:list。這是一種通用的寫法,冒號前面是外掛字首,後面是該外掛的目標。

7、外掛繫結

 maven的生命週期與外掛相互繫結,用以完成實際的構建任務。具體而言,是生命週期的階段與外掛的目標相互繫結,已完成某個具體的構建任務。例如專案編譯這一任務,它對應了default生命週期的compile階段,而maven-compiler-plugin這一外掛的compile目標能夠完成該任務,因此將他們繫結。

7.1內建繫結

 maven在核心為一些主要的生命週期接到繫結了很多外掛的目標,如下:
     clean和site生命週期相對簡單。

clean clean:clean

site site:site
site-deploy site:deploy


     default生命週期與外掛目標的繫結關係有點複雜一些。這是因為對於任何專案來說,例如jar專案和war專案,他們的專案清理和站點生成任務是一樣的,不過構建過程會有區別。例如jar專案需要打成jar包,而war專案需要打成war包。
     由於專案的打包型別會影響構建的具體過程,因此,default生命週期的階段與外掛目標的繫結關係有專案打包型別所決定的,打包型別是通過pom中的packaging元素定義的。最常見的打包型別是jar,它也是預設的打包型別。基於該打包型別,default生命週期的內建繫結關係如下:

process-resources resources:resources
compile compiler:compile
process-test-resources resources:testResources
test-compile compiler:testCompile
test surefire:test
package ejb:ejb or ejb3:ejb3 or jar:jar or par:par or rar:rar or war:war
install install:install
deploy deploy:deploy

 

7、2自定義繫結

     除了內建繫結以為,使用者還能夠自己選擇獎某個外掛目標繫結到生命週期的某個階段以執行更多更特色的任務。

<!-- 自動複製資原始檔件到根目錄 -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-resources-plugin</artifactId>
				<version>2.6</version>
				<configuration>
					<includeEmptyDirs>true</includeEmptyDirs>
					<encoding>GBK</encoding>
					<nonFilteredFileExtensions>
						<nonFilteredFileExtension>exe</nonFilteredFileExtension>
						<nonFilteredFileExtension>zip</nonFilteredFileExtension>
						<nonFilteredFileExtension>vbs</nonFilteredFileExtension>
						<nonFilteredFileExtension>sh</nonFilteredFileExtension>
					</nonFilteredFileExtensions>
				</configuration>
				<executions>
					<execution>
						<id>copy-resources</id>
						<phase>validate</phase>
						<goals>
							<goal>copy-resources</goal>
						</goals>
						<configuration>
							<includeEmptyDirs>true</includeEmptyDirs>
							<outputDirectory>${project.build.directory}</outputDirectory>
							<excludes>
								<exclude>agentmanager.jsmooth</exclude>
								<exclude>assembly.xml</exclude>
							</excludes>
							<resources>
								<resource>
									<directory>src/main/resources/</directory>
									<filtering>true</filtering>
								</resource>
							</resources>
						</configuration>
					</execution>
				</executions>
			</plugin>


     如上圖定義了一個id為copy-resources的任務,繫結到default生命週期的validate階段,繫結的外掛為maven-resources-plugin,外掛目標為copy-resources。即用外掛的copy-resources功能來實現專案資原始檔的拷貝。

<!-- 自動複製maven依賴包到lib目錄 -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-dependency-plugin</artifactId>
				<version>2.1</version>
				<executions>
					<execution>
						<id>copy</id>
						<phase>install</phase>
						<goals>
							<goal>copy-dependencies</goal>
						</goals>
						<configuration>
							<outputDirectory>lib</outputDirectory>
						</configuration>
					</execution>
				</executions>
			</plugin>


同上,定義了一個id為copy的任務,利用外掛maven-dependency-plugin的copy-dependencies目標繫結到default生命週期的install階段,來實現專案依賴的jar包的自動複製。

     當外掛目標被繫結到不同的生命週期階段時候,其執行順序會有生命週期階段的先後順序決定的。如果多個目標被繫結到同一個階段,他們的執行順序是由外掛宣告的先後順序決定目標的執行順序

8、外掛配置


 使用者可以配置外掛目標的引數,進一步調整外掛目標所執行的任務。

8、1命令列外掛配置

 如 $mvn install -Dmaven.test.skip=true 的意義即跳過測試步驟。
      引數-D的java自帶的,其功能是通過命令列設定一個java系統屬性,maven簡單地重用了該引數以實現外掛引數的配置。

8、2pom中外掛全域性配置

如專案編譯使用1.6版本的原始檔,生成與JVM1.6相容的位元組碼檔案,如下:

<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.3.2</version>
				<configuration>
					<source>1.6</source>
					<target>1.6</target>
				</configuration>
			</plugin>


 

9、獲取外掛描述資訊

    $mvn help:describe-Dplugin=org.apache.maven.plugins:maven-compiler-plugin:2.1  來獲取外掛的詳細資訊
    可以簡化為:
    $mvn help:describe-Dplugin=compiler
    如果僅僅描述外掛目標的資訊,可以加上goal引數:
    $mvn help:describe-Dplugin=compiler-Dgoal=compile
    如果想輸出更詳細的資訊,可以加上detail引數:
    $mvn help:describe-Dplugin=compiler-Ddetail



相關文章