Maven學習5: 生命週期和插件

1. maven的生命週期

1.1 生命週期介紹

  • maven的生命週期就是爲了對全部的構建過程進行抽象和統一。
  • 包含了項目的清理初始化編譯測試打包集成測試驗證部署站點生成等幾乎全部構建步驟。
  • 幾乎全部的項目構建,都能映射到這樣一個生命週期上。

1.2 生命週期詳解

  1. 三套生命週期html

    • maven包含三套相互獨立的生命週期。
    • clean生命週期:用於清理項目。
    • default生命週期:用於構建項目。
    • site生命週期:用於創建項目站點。
  2. 生命週期內部的階段java

    • 每一個生命週期包含多個階段(phase)。
    • 這些階段是有序的。
    • 後面的階段依賴前面的階段。當執行某個階段的時候,會先執行它前面的階段。
    • 用戶和maven最直接的交互就是調用這些生命週期階段。
  3. clean生命週期
    clean生命週期的目的是清理項目,它包含3個階段:apache

    clean生命週期階段 說明
    pre-clean 執行一些clean前須要完成的工做
    clean 清理上一次構建生成的文件
    post-clean 執行一些clean後須要完成的工做
  4. default生命週期
    default生命週期的目的是構建項目,它定義了真正構建時所須要完成的全部步驟,是全部生命週期中最核心的部分。
    包含23個階段:詳細介紹segmentfault

    default生命週期階段 說明
    validate 驗證項目是否正確而且全部必要信息均可用
    initialize 初始化構建狀態,好比設置屬性值、建立目錄
    generate-sources 生成包含在編譯階段中的任何源代碼
    process-sources 處理源代碼,好比說,過濾任意值
    generate-resources 生成將會包含在項目包中的資源文件
    process-resources 複製和處理資源到目標目錄,爲打包階段最好準備
    compile 編譯項目的源代碼
    process-classes 處理編譯生成的文件,好比說對Java class文件作字節碼改善優化
    generate-test-sources 生成包含在編譯階段中的任何測試源代碼
    process-test-sources 處理測試源代碼,好比說,過濾任意值
    generate-test-resources 爲測試建立資源文件
    process-test-resources 複製和處理測試資源到目標目錄
    test-compile 編譯測試源代碼到測試目標目錄
    process-test-classes 處理測試源碼編譯生成的文件
    test 使用合適的單元測試框架運行測試 , 測試代碼不會被打包或部署
    prepare-package 在實際打包以前,執行任何的必要的操做爲打包作準備
    package 將編譯後的代碼打包成可分發的格式,好比JAR
    pre-integration-test 在執行集成測試前進行必要的動做。好比說,搭建須要的環境
    integration-test 若有必要,將程序包處理並部署到能夠運行集成測試的環境中
    post-integration-test 執行集成測試完成後進行必要的動做。好比說,清理集成測試環境
    verify 運行任何檢查以驗證包是否有效並符合質量標準
    install 安裝項目包到maven本地倉庫,供本地其餘maven項目使用
    deploy 將最終包複製到遠程倉庫,供其餘開發人員和maven項目使用
  5. site生命週期
    site生命週期的目的是創建和發佈項目站點。
    Maven可以基於pom.xml所包含的信息,自動生成一個友好的站點,方便團隊交流和發佈項目信息。
    包含如下4個階段:服務器

    site生命週期階段 說明
    pre-site 執行一些在生成項目站點以前須要完成的工做
    site 生成項目站點文檔
    post-site 執行一些在生成項目站點以後須要完成的工做
    site-deploy 將生成的項目站點發布到服務器上
  6. mvn命令和生命週期
    從命令行執行maven任務的最主要方式就是調用maven的生命週期階段。
    須要注意的是,每套生命週期是相互獨立的,可是每套生命週期的階段是有先後依賴關係的。app

    • 格式: mvn 階段 [階段2] ...[階段n]
    • mvn clean:該命令調用clean生命週期的clean階段。框架

      • 實際執行的階段爲clean生命週期中的pre-clean和clean階段。
    • mvn test:該命令調用default生命週期的test階段。maven

      • 實際執行的階段爲default生命週期的從validate到test的全部階段。
      • 這也就解釋了爲何執行測試的時候,項目的代碼可以自動編譯。
    • mvn clean install:該命令調用clean生命週期的clean階段和default生命週期的install階段。ide

      • 實際執行的階段爲clean生命週期的pre-clean、clean階段,以及default生命週期的從validate到install的全部階段。
    • mvn clean deploy:該命令調用clean生命週期的clean階段和default生命週期的deploy階段。post

      • 實際執行的階段爲clean生命週期的pre-clean、clean階段,以及default生命週期的全部階段。
      • 包含了清理上次構建的結果、編譯代碼、運行單元測試、打包、將打好的包安裝到本地倉庫、將打好的包發佈到遠程倉庫等全部操做。

2. maven插件

2.1 插件目標

  • maven的核心僅僅定義了抽象的生命週期,具體的任務交給插件完成。

    • 每套生命週期包含多個階段,每一個階段執行什麼操做,都由插件完成。
  • 插件以獨立的構件形式存在。

    • 爲了可以複用代碼,每一個插件包含多個功能。
    • 插件中的每一個功能就叫作插件的目標(Plugin Goal),每一個插件中可能包含一個或者多個插件目標(Plugin Goal)

2.2 插件綁定

  • maven生命週期的階段與插件目標綁定,以完成某個具體的構件任務。

    • 好比項目編譯這個任務,對應了default生命週期階段的compile階段,而maven-compiler-plugin插件的compile目標可以完成該任務,所以將他們進行綁定,實現項目編譯任務。
  • 生命週期階段與插件進行綁定後,能夠經過mvn 階段來執行和這個階段綁定的插件目標。

2.3 內置綁定

  1. 說明
    爲了讓用戶幾乎不用任何配置就能構建maven項目,maven爲一些主要的生命週期階段綁定好了插件目標,當咱們經過命令調用生命週期階段時,綁定的插件目標就會執行對應的任務
  2. clean生命週期階段與插件目標的綁定關係

    生命週期階段 插件目標 做用
    pre-clean
    clean maven-clean-plugin:clean 刪除項目的輸出目錄
    post-clean
  3. default生命週期階段與插件目標的綁定關係(打包類型:jar)

    生命週期階段 插件目標 做用
    process-resources maven-resources-plugin:resources 複製主資源文件到主輸出目錄
    compile maven-compiler-plugin:compile 編譯主代碼到主輸出目錄
    process-test-resources maven-resources-plugin:testResources 複製測試資源文件到測試輸出目錄
    test-compile maven-compiler-plugin:testCompile 編譯測試代碼到測試輸出目錄
    test maven-surefire-plugin:test 執行測試用例
    package maven-jar-plugin:jar 建立項目jar包
    install maven-install-plugin:install 將項目輸出構件安裝到本地maven倉庫
    deploy maven-deploy-plugin:deploy 將項目輸出構件部署到遠程倉庫
  4. site生命週期階段與插件目標的綁定關係

    生命週期階段 插件目標 做用
    pre-site
    site maven-site-plugin:site 生成項目站點
    post-site
    site-deploy maven-site-plugin:deploy 將項目站點部署到遠程服務器
  5. 構建過程驗證

    • 與1.2生命週期詳解中6.mvn命令和生命週期示例相同,項目依然使用demo1做爲示例。
    • mvn clean

      • maven-clean-plugin:2.5:clean (default-clean): 插件artifactId:version:goal(goal-id), 刪除了項目輸出目錄。
      [INFO] Scanning for projects...
      [INFO] 
      [INFO] ---------------------------< com.john:demo1 >---------------------------
      [INFO] Building demo1 1.0-SNAPSHOT
      [INFO] --------------------------------[ jar ]---------------------------------
      [INFO] 
      [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ demo1 ---
      [INFO] Deleting /Users/john/Desktop/demo1/target
      [INFO] ------------------------------------------------------------------------
      [INFO] BUILD SUCCESS
      [INFO] ------------------------------------------------------------------------
      [INFO] Total time: 0.458 s
      [INFO] Finished at: 2019-12-22T16:28:50+08:00
      [INFO] ------------------------------------------------------------------------
    • mvn test

      • 調用default生命週期的test階段,實際執行的時候 default生命週期的validate階段直到test階段都要執行,每一個階段綁定的插件目標也會被執行。能夠看處處理資源、編譯源碼、處理測試資源、編譯測試源碼、測試插件目標都獲得了執行。
      [INFO] Scanning for projects...
      [INFO] 
      [INFO] ---------------------------< com.john:demo1 >---------------------------
      [INFO] Building demo1 1.0-SNAPSHOT
      [INFO] --------------------------------[ jar ]---------------------------------
      [INFO] 
      [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ demo1 ---
      [INFO] Using 'UTF-8' encoding to copy filtered resources.
      [INFO] Copying 1 resource
      [INFO] 
      [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ demo1 ---
      [INFO] Changes detected - recompiling the module!
      [INFO] Compiling 1 source file to /Users/john/Desktop/demo1/target/classes
      [INFO] 
      [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ demo1 ---
      [INFO] Using 'UTF-8' encoding to copy filtered resources.
      [INFO] Copying 1 resource
      [INFO] 
      [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ demo1 ---
      [INFO] Changes detected - recompiling the module!
      [INFO] Compiling 1 source file to /Users/john/Desktop/demo1/target/test-classes
      [INFO] 
      [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ demo1 ---
      [INFO] Surefire report directory: /Users/john/Desktop/demo1/target/surefire-reports
      
      -------------------------------------------------------
       T E S T S
      -------------------------------------------------------
      Running com.john.AppTest
      this is a test case
      arg is john
      Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.061 sec
      
      Results :
      
      Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
      
      [INFO] ------------------------------------------------------------------------
      [INFO] BUILD SUCCESS
      [INFO] ------------------------------------------------------------------------
      [INFO] Total time: 2.394 s
      [INFO] Finished at: 2019-12-22T16:32:23+08:00
      [INFO] ------------------------------------------------------------------------
    • mvn clean install

      • 該命令調用clean生命週期的clean階段和default生命週期的install階段。
      • (構建過程內容省略)
    • mvn clean deploy

      • 該命令調用clean生命週期的clean階段和default生命週期的deploy階段。
      • (構建過程內容省略)

2.4 自定義綁定

  1. 說明
    本身選擇將某個插件目標綁定到生命週期的某個階段上,使得maven項目在構建過程當中執行更多更富特點的任務。
  2. 舉例:建立項目的源碼jar包

    • 使用插件:org.apache.maven.plugins:maven-source-plugin:3.2.1
    • 插件目標:jar-no-fork

      • 這裏有個疑問:maven-source-plugin提供的jarjar-no-fork兩個目標均可以進行項目源碼的打包,爲何選擇jar-no-fork?
      • 解釋:
      • jar: Invokes the execution of the lifecycle phase: generate-sources prior to executing itself. jar這個插件目標又從新執行了在它前面的階段generate-sources
      • jar-no-fork不會從新執行在它前面的階段generate-sources
    • 綁定階段:package(默認),咱們這裏使用verify(在測試完成以後並將構件安裝到本地倉庫以前執行的階段。)
    • 具體配置(pom.xml)

      <build>
          <plugins>
              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-source-plugin</artifactId>
                  <version>3.2.1</version>
                  <executions>
                      <execution>
                          <id>attach-sources</id>
                          <phase>verify</phase>
                          <goals>
                              <goal>
                                  jar-no-fork
                              </goal>
                          </goals>
                      </execution>
                  </executions>
      
              </plugin>
          </plugins>
      </build>
    • 執行mvn verify

      [INFO] Scanning for projects...
      [INFO] 
      [INFO] ---------------------------< com.john:demo1 >---------------------------
      [INFO] Building demo1 1.0-SNAPSHOT
      [INFO] --------------------------------[ jar ]---------------------------------
      [INFO] 
      [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ demo1 ---
      [INFO] Using 'UTF-8' encoding to copy filtered resources.
      [INFO] Copying 1 resource
      [INFO] 
      [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ demo1 ---
      [INFO] Nothing to compile - all classes are up to date
      [INFO] 
      [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ demo1 ---
      [INFO] Not copying test resources
      [INFO] 
      [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ demo1 ---
      [INFO] Not compiling test sources
      [INFO] 
      [INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ demo1 ---
      [INFO] Tests are skipped.
      [INFO] 
      [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ demo1 ---
      [INFO] Building jar: /Users/john/Desktop/demo1/target/demo1-1.0-SNAPSHOT.jar
      [INFO] 
      [INFO] --- maven-source-plugin:3.2.1:jar-no-fork (attach-sources) @ demo1 ---
      [INFO] Building jar: /Users/john/Desktop/demo1/target/demo1-1.0-SNAPSHOT-sources.jar
      [INFO] ------------------------------------------------------------------------
      [INFO] BUILD SUCCESS
      [INFO] ------------------------------------------------------------------------
      [INFO] Total time: 2.101 s
      [INFO] Finished at: 2019-12-22T17:00:39+08:00
      [INFO] ------------------------------------------------------------------------

2.5 插件配置

  1. 命令行插件配置

    • 在maven命令中使用-D參數,並伴隨一個參數鍵=參數值的形式,來配置插件目標的參數。
    • 參數-D是java自帶的,其功能是經過命令行設置一個java系統屬性。
    • 例如,跳過執行測試目標,mvn clean pakcage -Dmaven.test.skip=true
  2. pom文件中插件全局配置

    • 用戶在pom文件聲明插件時,能夠對插件進行全局的配置。
    • 例如,配置maven-compiler-plugin編譯Java 1.8版本的源文件,生成與JVM 1.8兼容的字節碼文件。

      <build>
          <plugins>
              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-compiler-plugin</artifactId>
                  <version>3.8.1</version>
                  <configuration>
                      <!-- 編譯器版本 -->
                      <compilerVersion>1.8</compilerVersion>
                      <!-- 源碼版本 -->
                      <source>1.8</source>
                      <!-- 目標代碼版本 -->
                      <target>1.8</target>
                  </configuration>
              </plugin>
          </plugins>
      </build>

2.6 獲取插件信息

  1. 在線插件信息

    • Apache:Maven Plugins
    • 能夠查看插件介紹、插件目標、目標參數等等。
  2. 使用 maven-help-plugin 描述插件

    • 使用 maven-help-plugin 獲取插件信息。
    • 方式1:使用插件座標:mvn help:describe -Dplugin=groupId:artifactId:version
    • 方式2:使用插件目標前綴:mvn help:describe -Dplugin=Goal Prefix,目標前綴的做用是方便在命令行直接運行插件。
    • 若是要獲取插件的詳細描述,能夠在命令後加上-Ddetail參數。
    • 舉例:兩種方式獲取maven-compiler-plugin:3.8.1的插件描述信息

      • mvn help:describe -Dplugin=org.apache.maven.plugins:maven-compiler-plugin:3.8.1
      • mvn help:describe -Dplugin=compiler
      • 過程輸出

        [INFO] Scanning for projects...
        [INFO] 
        [INFO] ---------------------------< com.john:demo1 >---------------------------
        [INFO] Building demo1 1.0-SNAPSHOT
        [INFO] --------------------------------[ jar ]---------------------------------
        [INFO] 
        [INFO] --- maven-help-plugin:3.2.0:describe (default-cli) @ demo1 ---
        [INFO] org.apache.maven.plugins:maven-compiler-plugin:3.8.1
        
        Name: Apache Maven Compiler Plugin
        Description: The Compiler Plugin is used to compile the sources of your
          project.
        Group Id: org.apache.maven.plugins
        Artifact Id: maven-compiler-plugin
        Version: 3.8.1
        Goal Prefix: compiler
        
        This plugin has 3 goals:
        
        compiler:compile
          Description: Compiles application sources
        
        compiler:help
          Description: Display help information on maven-compiler-plugin.
            Call mvn compiler:help -Ddetail=true -Dgoal=<goal-name> to display
            parameter details.
        
        compiler:testCompile
          Description: Compiles application test sources.
        
        For more information, run 'mvn help:describe [...] -Ddetail'
        
        [INFO] ------------------------------------------------------------------------
        [INFO] BUILD SUCCESS
        [INFO] ------------------------------------------------------------------------
        [INFO] Total time: 2.162 s
        [INFO] Finished at: 2019-12-22T17:42:55+08:00
        [INFO] ------------------------------------------------------------------------
  3. 從命令行調用插件

    • maven命令幫助:mvn -h
    • 輸出:usage: mvn [options] [<goal(s)>] [<phase(s)>]
    • 獲取項目依賴樹:mvn dependency:tree
    • 分析當前項目依賴:mvn dependency:analyze
    • 查看當前項目的已解析依賴:mvn dependency:list
    • 查看項目最終pom.xml文件:mvn help:effective-pom

2.7 插件解析

maven簡化了插件的使用和配置,可是具體maven是怎麼解析插件的呢?

  1. 插件倉庫

    • 與依賴構件同樣,插件構件一樣基於座標存儲在maven倉庫中。在須要的時候,maven會從本地倉庫查找插件,若是不存在,則從遠程倉庫查找。找到後下載到本地倉庫使用。
    • 配置插件倉庫,插件倉庫與依賴構件倉庫是分開配置的。
    • 在項目pom文件pluginRepositories -> pluginRepository元素中配置插件倉庫。
    • 具體配置(maven 內置的插件遠程倉庫):

      <pluginRepositories>
        <pluginRepository>
          <id>central</id>
          <name>Central Repository</name>
          <url>https://repo.maven.apache.org/maven2</url>
          <layout>default</layout>
          <snapshots>
            <enabled>false</enabled>
          </snapshots>
          <releases>
            <updatePolicy>never</updatePolicy>
          </releases>
        </pluginRepository>
      </pluginRepositories>
  2. 插件的默認groupId

    • org.apache.maven.plugins,配置時不建議省略。
  3. 解析插件版本

    • maven在超級pom中爲全部核心插件定義了版本。
    • 使用插件時候,應該一直顯式設定版本。
  4. 解析插件前綴

    • 插件前綴(Goal Prefix)與groupId:artifactId是一一對應的,這種對應關係存儲在倉庫元數據中。

      • 示例:匹配關係
      • 本地倉庫插件元數據文件位置:~/.m2/repository/org/apache/maven/plugins/maven-metadata-central.xml

        <metadata>
            <plugins>
                <plugin>
                    <name>Apache Maven Clean Plugin</name>
                    <prefix>clean</prefix>
                    <artifactId>maven-clean-plugin</artifactId>
                </plugin>
                <plugin>
                    <name>Apache Maven Compiler Plugin</name>
                    <prefix>compiler</prefix>
                    <artifactId>maven-compiler-plugin</artifactId>
                </plugin>
            </plugins>
        </metadata>
    • 默認的插件倉庫groupId:org.apache.maven.plugins
    • 配置本身的插件倉庫元數據:

      • 用戶的maven配置文件:~/.m2/settings.xml
      • settings -> pluginGroups -> pluginGroup元素中配置。

        <settings>
          <pluginGroups>
            <pluginGroup>com.your.plugins</pluginGroup>
          </pluginGroups>
        </settings>
相關文章
相關標籤/搜索