maven實戰筆記

1. What is maven?

  • Maven主要服務於基於java平臺的項目構建、依賴管理和項目信息管理。
  • 最大化消除了構建的重複,抽象了構建生命週期
  • 大量成熟插件

2. 配置文件

<proxy>
        <id>proxy</id>
        <active>true</active>
        <protocol>http</protocol>
        <username></username>
        <password></password>
        <host>proxy.zte.com.cn</host>
        <port>80</port>
        <nonProxyHosts>proxy.zte.com.cn:80|192.168.*.*|*.zte.com.cn|10.*.*.*|*.*.zte.intra</nonProxyHosts>
        //哪些主機名不需要代理
  </proxy>
<modelVersion>4.0.0</modelVersion> 指定了當前POM模型的版本

3. 入門

scope : test,默認compile
mvn clean compile
mvn clean test

插件配置:
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.7.0</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>
    </plugins>
</build>

如果沒有指定打包類型,默認爲jar,mvn clean package
其他maven項目如果需要直接引用的話,還需要install,將項目輸出的jar安裝到本地倉庫 mvn clean install
默認打包生成的jar是不能直接運行的,帶有main方法的類信息不會加載到manifest中,生成可執行jar需要藉助

        <plugin>  
            <groupId>org.apache.maven.plugins</groupId>  
            <artifactId>maven-shade-plugin</artifactId>  
            <version>1.4</version>  
            <executions>  
                <execution>  
                    <phase>package</phase>  
                    <goals>  
                        <goal>shade</goal>  
                    </goals>  
                    <configuration>  
                        <filters>  
                            <filter>  
                                <artifact>*:*</artifact>  
                                <excludes>  
                                    <exclude>META-INF/*.SF</exclude>  
                                    <exclude>META-INF/*.DSA</exclude>  
                                    <exclude>META-INF/*.RSA</exclude>  
                                </excludes>  
                            </filter>  
                        </filters>  
                        <transformers>  
                            <transformer  
                                implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">  
                                <mainClass>com.lcifn.Application</mainClass>  
                            </transformer>  
                            <transformer  
                                implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">  
                                <resource>META-INF/spring.handlers</resource>  
                            </transformer>  
                            <transformer  
                                implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">  
                                <resource>META-INF/spring.schemas</resource>  
                            </transformer>  
                        </transformers>  
                    </configuration>  
                </execution>  
            </executions>  
        </plugin>

4. Archetype

骨架:基本的目錄結構和pom的文件內容
mvn archetype:generate
完全可以自己開發骨架

5. 座標

爲各種構件引入了秩序,groupId artifactId version packaging classifier(不能直接指定)

6. 依賴

依賴範圍控制與三種classpath(編譯、測試、運行的classpath)的關係

  • compile: 對三種都有效,默認(spring-core)
  • test:測試classpath(junit)
  • provided:編譯和測試(servlet-core)
  • runtime:測試和運行(JDBC,編譯時只需要接口,運行纔要實現)
  • system:關係與provided一致,一定要指定systemPath,不是通過maven倉庫解析的,謹慎使用,可引用環境變量(${java.home})
  • import: 不會對三種classpath產生實際影響

依賴範圍也影響依賴的傳遞性:

compile test provided runtime
compile compile - -
test test - -
provided provided - provided
runtime runtime - -

依賴解調

  • 兩個版本:路徑最近優先
  • 路徑一樣,第一聲明者優先
    可選依賴:<optional>標籤,依賴不會被傳遞

依賴排除

利用<exclusions> <exclusion>

依賴歸類

有些依賴來自同一項目的不同模塊,版本會一起升級,應該在一個唯一的地方定義版本。如:

<properties>
  <springframework.version>2.5.6</springframework>
</properties>
引用 ${springframework.version}

依賴優化

查看已解析依賴:mvn dependency:list``````mvn dependecny:tree
還有mvn dependency:analyse分析當前項目依賴

7. maven倉庫

實際的項目不再各自存儲依賴文件,統一位置是倉庫,需要的時候maven會根據座標找到並使用
倉庫的路徑:groupId/artifactId/version/artifactId-version-classifier.packaging

  • 本地倉庫
  • 中央倉庫
  • 私服(私服軟件:如Nexus)
  • 其他公共庫

在pom中配置遠程倉庫

<repositories>
    <repository>
      <id>central</id>
      <name>Central Repository</name>
      <url>https://repo.maven.apache.org/maven2</url>
      <layout>default</layout>
      <snapshots>
        <enabled>false</enabled>
      </snapshots>
      <releases>
        <enabled>false</enabled>
      </releases>
      <layout>default</layout> 表示是maven2或3的默認佈局
    </repository>
  </repositories>``
<snapshots>
  <enabled>true</enabled>
  <updatePolicy>daily</updatePolicy> daily/never/always/interval:分鐘
  <checksumPolicy>ignore</checksumPolicy>
</snapshots>

默認值是daily mvn clean install -U 強制下載最新快照

checksumPolicy:構建部署到倉庫時會同時部署校驗和文件,下載構建會驗證校驗和文件,如果失敗?warn/fail/ignore

遠程倉庫認證

在settings文件中的’’’ ‘’'中配置用戶名密碼,其中的id必須和pom中倉庫id對上

部署到遠程倉庫

<!-- 在POM中配置構件部署地址 -->
    <distributionManagement>
        <!-- 發佈版本的構件的倉庫 -->
        <repository>
            <id>proj-release</id>
            <name>proj release repository</name>
            <url>http://192.168.1.100/content/repositories/proj-release</url>
        </repository>
        <!-- 快照版本的倉庫-->
        <snapshotRepository>
            <id>proj-snapshots</id>
            <name>proj snapshot repository</name>
            <url>http://192.168.1.100/content/repositories/proj-snapshots</url>
        </snapshotRepository>
    </distributionManagement>

如果不指定插件的版本,maven以RELEASE策略,自動解析最新的發佈版本構建(不是快照)

8. 鏡像

倉庫X可以提供倉庫Y的所有存儲內容,認爲X是Y的一個鏡像,在settings中可以使用鏡像代替中央倉庫

<mirrors>
     <mirror>
        <id>alimaven</id>
        <name>aliyun maven</name>
        <url>http://maven.aliyun.com/mvn/view</url>
        <mirrorOf>central</mirrorOf>
    </mirror>
    <mirror>
        <id>jboss-public-repository-group</id>
        <mirrorOf>central</mirrorOf>
        <name>JBoss Public Repository Group</name>
        <url>http://repository.jboss.org/nexus/content/groups/public</url>
    </mirror>
</mirrors>

mirrorOf:

  • *所有遠程倉庫
  • external:* 所有遠程,localhost除外,使用file://協議除外
  • repo1,repo2 倉庫repo1,repo2
  • *,!repo1repo1除外

鏡像需要權限也在<server>配置


在settings.xml中配置遠程倉庫
<settings>  
  ...  
  <profiles>  
    <profile>  
      <id>dev</id>  
      <!-- repositories and pluginRepositories here-->   把上面的內容粘貼到這裏。。。
    </profile>  
  </profiles>  
  <activeProfiles>  
    <activeProfile>dev</activeProfile>  
  </activeProfiles>  
  ...  
</settings>  
這裏我們定義一個id爲dev的profile,將所有repositories以及pluginRepositories元素放到這個profile中,然後,使用<activeProfiles>元素自動激活該profile。這樣,你就不用再爲每個POM重複配置倉庫。

使用profile爲settings.xml添加倉庫提供了一種用戶全局範圍的倉庫配置。

9. 生命週期

生命週期抽象了構建的各個步驟,定義了次序,沒提供具體實現。誰實現?插件
maven提供了默認插件簡化和穩定構建,用戶可通過配置現有插件或自己編寫插件自定義構建行爲。

三套週期

clean週期: 後一個步驟會順序執行前面所有步驟

  1. pre-clean: clean之前要完成的工作
  2. clean :清理上一次構建生成的文件
  3. post-clean:clean之後要完成的工作

default週期:

  1. 驗證(validate) 驗證項目是正確的,所有必要的信息可用。
  2. 初始化(initialize) 初始化構建狀態,例如設置屬性或創建目錄。
  3. 產生來源(generate-sources) 生成包含在編譯中的任何源代碼。
  4. 流程源(process-sources) 處理源代碼,例如過濾任何值。
  5. 生成資源(generate-resources) 生成包含在包中的資源。
  6. 流程資源(process-resources) 將資源複製並處理到目標目錄中,準備打包。
  7. 編譯(compile) 編譯項目的源代碼。
  8. 工藝類(process-classes) 從編譯後處理生成的文件,例如對Java類進行字節碼增強。
  9. 生成測試來源(generate-test-sources) 生成包含在編譯中的任何測試源代碼。
  10. 流程測試來源(process-test-sources) 處理測試源代碼,例如過濾任何值。
  11. 生成測試資源(generate-test-resources) 創建測試資源。
  12. 流程測試資源(process-test-resources) 將資源複製並處理到測試目標目錄中。
  13. 測試編譯(test-compile) 將測試源代碼編譯到測試目標目錄中
  14. 流程檢驗類(process-test-classes) 從測試編譯中處理生成的文件,例如對Java類進行字節碼增強。對於Maven 2.0.5及以上版本。
  15. 測試(test) 使用合適的單元測試框架運行測試。這些測試不應該要求代碼被打包或部署。
  16. 製備包(prepare-package) 在實際包裝之前,執行必要的準備包裝的操作。這通常會導致打包的處理版本的包。(Maven 2.1及以上)
  17. 打包(package) 採取編譯的代碼,並以其可分發的格式(如JAR)進行打包。
  18. 預集成測試(pre-integration-test) 在執行集成測試之前執行所需的操作。這可能涉及諸如設置所需環境等。
  19. 集成測試(integration-test) 如果需要,可以將該包過程並部署到可以運行集成測試的環境中。
  20. 整合後的測試(post-integration-test) 執行集成測試後執行所需的操作。這可能包括清理環境。
  21. 校驗(verify) 運行任何檢查以驗證包裝是否有效並符合質量標準。
  22. 安裝(install) 將軟件包安裝到本地存儲庫中,以作爲本地其他項目的依賴關係。
  23. 部署(deploy) 在集成或發佈環境中完成,將最終軟件包複製到遠程存儲庫,以與其他開發人員和項目共享。

site週期: 處理你的項目站點文檔的創建。

  1. 預網站(pre-site) 在實際的項目現場生成之前執行所需的進程
  2. 網站(site) 生成項目的站點文檔
  3. 後網站(post-site) 執行完成站點生成所需的進程,並準備站點部署
  4. 網站部署(site-deploy) 將生成的站點文檔部署到指定的Web服務器

10. 插件

插件目標

一個插件會聚合多種功能,每個功能就是一個目標

dependency: analyze、dependency:tree、dependency:list
compiler:compile、surefire:test

生命週期綁定了插件目標。
多個目標綁到一個階段,按照插件聲明的先後順序決定執行順序

插件配置

  • 從命令行配置插件:如 mvn install -Dmaven.test.skip = true
  • pom中配置插件:
<build>  
      <plugins>  
        <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>  
      </plugins>  
    </build>  
 <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.1.1</version>
    <configuration>
      <webResources>
        <resource>
          <directory>src/main/webapp</directory>
          <excludes>
            <exclude>**/*.jpg</exclude>
          </excludes>
        </resource>
      </webResources>
    </configuration>
  </plugin>

任務配置:

<plugin>
67             <groupId>org.apache.maven.plugins</groupId>
68             <artifactId>maven-clean-plugin</artifactId>
69             <version>${plugin.version}</version>
70             <executions>
71                 <execution>
72                     <id>auto-clean</id>
73                     <!-- clean生命週期clean階段 -->
74                     <phase>clean</phase>
75                     <goals>
76                         <!-- 執行clean插件的clean目標 -->
77                         <goal>clean</goal>
78                     </goals>
79                 </execution>
80             </executions>
81         </plugin>

從命令行調用插件,因爲有些插件不適合綁定在生命週期

插件的倉庫

插件的遠程倉庫用<pluginRepository>配置
在pom中配置插件時,如果是maven官方插件,可省略groupId

解析插件版本

maven在超級pom中爲所有核心插件指定了版本,如果不屬於核心插件,會檢查倉庫中可用版本,maven3默認的是RELEASE
可以在settings中配置<pluginGroups>這樣除了掃描org.apahce.maven.plugins和org.codehaus.mojo外,還會掃描配置的

11. 聚合與繼承

聚合

maven聚合特性:把多模塊聚合在一起構建;繼承:抽取模塊相同的依賴和配置,統一管理。

額外的tip:測試用例測試接口而不是實現,測試代碼不能引入實現類

  • 父類結構: 多模塊的maven項目,必須有一個額外的模塊來聚合所有的模塊,packaging爲pom,否則無法構建;<modules>實現模塊的聚合,每一個值是一個當前pom的相對目錄。一般與artifactId一致(模塊存放的目錄)
  • 平行結構: pom需要改動 <module>../account-email</module>

繼承

創建parent模塊,packaging還是爲pom,繼承的時候子模塊用<parent>來繼承

  • <relativePath>默認是../pom.xml,默認父pom在上一層目錄
  • <relativePath>../account-parent/pom/xml表示在與子模塊平行的parent目錄下

maven會根據relativePath查找父模塊,沒找到會到本地倉庫找

可繼承的pom元素

  1. 子模塊會默認繼承父的groupId和version,一樣的話就不需要再配置了
  2. description :項目的描述信息;
  3. organization :項目的組織信息;
  4. inceptionYear :項目的創始年份;
  5. url :項目的 url 地址
  6. develoers :項目的開發者信息;
  7. contributors :項目的貢獻者信息;
  8. distributionManagerment :項目的部署信息;
  9. issueManagement :缺陷跟蹤系統信息;
  10. ciManagement :項目的持續繼承信息;
  11. scm :項目的版本控制信息;
  12. mailingListserv :項目的郵件列表信息;
  13. properties :自定義的 Maven 屬性;
  14. dependencies :項目的依賴配置;
  15. dependencyManagement :醒目的依賴管理配置;
  16. repositories :項目的倉庫配置;
  17. build :包括項目的源碼目錄配置、輸出目錄配置、插件配置、插件管理配置 等;
  18. reporting :包括項目的報告輸出目錄配置、報告插件配置等。

dependencyManagement

dependencyManagement能讓子模塊繼承到依賴配置,但只是對版本進行管理,不會實際引入jar,約束dependencies依賴使用。在子模塊只要配置簡單的groupId和artifactId就能獲得對應的依賴信息

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.test.sample</groupId>
            <artifactid>base-parent1</artifactId>
            <version>1.0.0-SNAPSHOT</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

import依賴範圍,可以將目標pom中的dependencyManagement引入,提供了除複製和繼承外的第三種方法,注意:打包類型必須是pom

插件管理 pluginManagement 類似

簡化: 一個POM既是聚合pom又是繼承pom也沒關係

約定優於配置

maven有一些固定的項目組織結構,減少交流成本,如非必要不要改,比如<sourceDirectory>src/java</sourceDirectory>

這些約定來自於超級pom

reactor反應堆

依次讀取pom,如果沒有依賴,構建,有依賴,先構建依賴的模塊,不允許出現依賴循環。

反應堆裁剪命令:

  • -am,–also-make:同時構建所列模塊的依賴模塊
  • -amd,-also-make-dependents:同時構建依賴於所列模塊的模塊
  • -pl,–projects:構建指定的模塊,模塊間用逗號分隔
  • -rf,-resume-from:在完整的反應堆構建順序基礎上指定從哪個模塊開始構建

舉例:使用-pl來指定構建某幾個模塊,並增加 -am 參數同時構建依賴的模塊,mvn clean -pl account-service -am; 使用 -amd 選項可以同時構建依賴於所列模塊的模塊, mvn clean -pl account-email -amd; 使用 -rl 選項可以在完整的反應堆構建順序基礎上指定從哪個模塊開始構建,mvn clean -rf account-email

12. maven測試

maven重要職責之一是自動運行單元測試,插件爲maven-surefire-plugin,test目標會自動執行測試源碼路徑(默認爲src/test/java)下所有符合一組命名模式的測試類:

  • **/Test*.java: 任何子目錄下以Test開頭的類
  • **/*Test.java: 任何子目錄下以Test結尾的類
  • **/*TestCase.java: 任何子目錄下以TestCase結尾的類

以Tests結尾的類不會自動執行

跳過測試

-DskipTests可跳過測試運行,-Dmaven.test.skip = true跳過測試代碼的編譯和運行

指定某個測試

  • mvn test -Dtest=測試用例類名
  • mvn test -Dtest=Random*Test 模糊匹配
  • mvn test -Dtest=Random*Test,類名2 指定多個
  • 但如果沒有匹配到任何測試類,會報錯,可以mvn test -Dtest -DfailIfNoTests=false

包含與排除

<build>
   <plugins>
     <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-surefire-plugin</artifactId>
       <version>2.20</version>
       <configuration>
         <!-- 包含 -->
         <includes>
           <include>**/*Tests.java</include>
         </includes>
         <!-- 排除 -->
         <excludes>
           <exclude>**/Abstract*.java</exclude>
         </excludes>
       </configuration>
     </plugin>
   </plugins>
</build>

測試覆蓋率報告

cobertura是一個開源測試覆蓋率統計軟件 mvn cobertura:cobertura

重用測試代碼

測試代碼默認是不打包的,插件maven-jar-plugin有兩個目標,分別是jar和test-jar,前者內置綁定到package生命週期,後者默認綁定到package,但沒有內置綁定,要顯式聲明

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>3.0.2</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>test-jar</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <excludes>
            <!--注意這玩意從編譯結果目錄開始算目錄結構-->
            <exclude>/*.properties</exclude>
            <exclude>/*.xml</exclude>
        </excludes>
    </configuration>
</plugin>

測試被打成jar之後,可被其他模塊的測試代碼包含到dependency中,type test-jar

13. maven構建web項目

  1. 顯式指定打包方式 war
+src

    ++main

     +++java(源代碼)

     +++resources(資源文件)

     +++webapp(web應用目錄)

       ++++WEB-INF
           web.xml
       ++++靜態資源
    ++test

     +++java(測試源代碼)

     +++resources(測試資源文件)
  1. 一個典型war文件有它固定的結構,maven規定的結構和war有一定的對應關係
  2. web.xml中會配置多個sevlet對應不同的url,這是沒有用jersey的一種url映射方式?用jersey的時候也有這些配置,有什麼區別呢,jersey裏的servlet幹啥的

jetty-maven-plugin

詳細的配置,用法以及需要修改settings.xml,這不是官方的默認插件,groupid不同。還可以設置很多web級的配置,比如context。
https://www.cnblogs.com/liupeizhi/articles/2701348.html

mvn jetty:run mvn jetty:run -Djetty.port = 9999
插件自動掃描到web的修改,熱部署

Cargo自動化部署

自動化地將web應用部署至本地或遠程的web容器中

cargo:start的生命週期依賴於maven實例的生命週期,也就是說,maven構建成功或者失敗之後,cargo插件的生命週期也自動停止了;而cargo:run不同,不管maven是否構建成功或者失敗,都必須手工去按Ctrl + C來停止。

  1. 部署到本地Web容器

    standalone模式

在standalone模式,Cargo會從Web容器的安裝目錄複製一份配置到用戶指定的目錄,然後在此基礎上部署應用,每次重新構建的時候,這個目錄都會被清空,所有配置被重新生成

<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.4.9</version>
<configuration>
  <container>
    <containerId>tomcat7x</containerId>
    <home>/usr/local/devtools/apache-tomcat-7.0.55</home>
  </container>
  <configuration>
    <type>standalone</type>
    <home>${project.build.directory}/tomcat7x</home>
    <properties>
      <!-- 更改監聽端口 -->
      <cargo.servlet.port>8088</cargo.servlet.port>
    </properties>
  </configuration>
</configuration>
</plugin>

mvn cargo:run
2. 部署到本地Web容器

existing模式

在existing模式下,用戶需要指定現有的web容器配置目錄,然後Cargo會直接使用這些配置並將應用部署到其對應的位置

<plugin>
	<groupId>org.codehaus.cargo</groupId>
	<artifactId>cargo-maven2-plugin</artifactId>
	<version>1.4.9</version>
	<configuration>
		<container>
			<containerId>tomcat7x</containerId>
			<home>/usr/local/devtools/apache-tomcat-7.0.55</home>
		</container>
		<configuration>
			<type>existing</type>
			<home>/usr/local/devtools/apache-tomcat-7.0.55</home>
		</configuration>
	</configuration>
</plugin>
  1. 部署到遠程正在運行的容器

    更多配置詳見插件解析,這裏是最簡單的

    配置好之後就可以運行mvn cargo:redeploy 來部署應用了(必須保證tomcat是running狀態,否則沒法部署),如果容器中已經部署的當前應用,Cargo會先卸載掉原來的應用,然後再重新部署。

<plugin>
	<groupId>org.codehaus.cargo</groupId>
	<artifactId>cargo-maven2-plugin</artifactId>
	<version>1.4.9</version>
	<configuration>
		<container>
			<containerId>tomcat7x</containerId>
			<type>remote</type>
		</container>
		<configuration>
			<type>runtime</type>
			<properties>
				<cargo.tomcat.manager.url>http://localhost:8080/manager/text</cargo.tomcat.manager.url>
        <cargo.remote.username>admin</cargo.remote.username>
        <cargo.remote.password>password</cargo.remote.password>
      </properties>
		</configuration>
	</configuration>
</plugin>

14. 版本管理和版本控制

版本管理:項目整體版本的演變過程管理;版本控制:追蹤代碼的每一個變更

管理

發佈的條件:

  1. 自動化測試全通過
  2. 沒有配置任何快照版本依賴
  3. 沒有配置任何快照版本插件
  4. 項目所包含的代碼全部提交到版本控制系統中

命名的含義:<主版本>.<次版本>.<增量版本> - <里程碑版本>

  1. 主版本:重大架構變更
  2. 次版本:較大範圍功能增加和變化
  3. 增量版本:重大bug修復
  4. 里程碑:通常表示與正式版本比不太穩定

後面兩個是可選的

標籤

  1. 主幹:項目開發代碼的主體,是從項目開始到當前都處於活動的狀態
  2. 分支:從主幹的某個點分離出來的代碼拷貝。通常能夠在不影響主幹的前提下。在這裏進行重大的bug修復或者實驗性質的開發。假設達到了預期的目的,通常將這裏的變更合併到主幹中去。
  3. 標籤:標識主幹或者分支某個點的狀態,代表項目的某個穩定狀態

maven RELEASE plugin

該插件主要有三個目標:release: prepare, release: rollback, release: perform (什麼是插件目標),在介紹分支自己主動化的時候還會引入branch目標

release:prepare -DautoVersionSubmodules 準備版本號公佈。依次運行下列操作

  1. 檢查項目是否有未提交的代碼
  2. 檢查項目是否有快照版本號依賴
  3. 依據用戶的輸入將快照版本號升級爲公佈版
  4. 將POM中的SCM信息更新爲標籤地址
  5. 基於改動後的POM運行maven構建
  6. 提交POM變更
  7. 基於用戶輸入爲代碼打標籤
  8. 將代碼從公佈版升級爲新的快照版
  9. 提交POM變更

release: rollback

回退release: prepare所運行的操作。

將POM回退至release:prepare之前的狀態。並提交。

注:該步驟不會刪除release:prepare生成的標籤,須要用戶手動刪除

release: perform

運行版本號公佈

簽出release:prepare生成的標籤中的源碼,並在此基礎上運行mvn deploy命令打包並部署構件至倉庫

  • pom中需要配置SCM信息,插件中要配置configuration告訴標籤目錄,需要知道版本控制系統的主幹、標籤等地址信息
  • 超級pom中的profile會在特定情況下激活,可以在maven任何命令行指令指定屬性爲true,執行release:perform的時候,插件會自動成聖值爲true的performRelease屬性。
  • 如果需要跳過單元測試,可以加入參數 -Darguments="-DskipTests",直接使用-Dmaven.test.skip=true是無效的。
<project>
    <scm>
        <connection>scm:git:http://項目git地址</connection>
        <url>項目git地址(不加'.git後綴')</url>
        <developerConnection>scm:項目git地址</developerConnection>
    </scm>
</project>


<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-release-plugin</artifactId>
    <version>2.5.3</version>
    <configuration>
        <tagNameFormat>v@{project.version}</tagNameFormat>
        <autoVersionSubmodules>true</autoVersionSubmodules>
    </configuration>
</plugin>

release: branch

mvn release:branch -DbranchName=1.1.x -DupdateBranchVersions=true -DupdateWorkingCopyVersions=false

這是maven-release-plugin的branch目標,我們指定branch的名稱爲1.1.x,表示這裏會有版本1.1.1, 1.1.2等等。updateBranchVersions=true的意思是在分支中更新版本,而updateWorkingCopyVersions=false是指不更改當前工作目錄(這裏是trunk)的版本。

在運行該命令後,我們會遇到這樣的提示:

What is the branch version for “Unnamed - org.myorg:myapp:jar:1.1-SNAPSHOT”? (org.myorg:myapp) 1.1-SNAPSHOT: :

——“分支中的版本號是多少?默認爲1.1-SNAPSHOT” 這時我們想要的版本是1.1.1-SNAPSHOT,因此輸入1.1.1-SNAPSHOT,回車,maven繼續執行直至結束。

接着,我們瀏覽svn倉庫,會看到這樣的目錄:https://192.168.1.100:8443/svn/myapp/branches/1.1.x/,打開其中的POM文件,其版本已經是1.1.1-SNAPSHOT。

GPG GunPG是pretty good privacy PGP標準的一個實現

GPG是GNU Privacy Guard的縮寫,是自由軟件基金會的GNU計劃的一部分。它是一種基於密鑰的加密方式,使用了一對密鑰對消息進行加密和解密,來保證消息的安全傳輸。一開始,用戶通過數字證書認證軟件生成一對公鑰和私鑰。任何其他想給該用戶發送加密消息的用戶,需要先從證書機構的公共目錄獲取接收者的公鑰,然後用公鑰加密信息,再發送給接收者。當接收者收到加密消息後,他可以用自己的私鑰來解密,而私鑰是不應該被其他人拿到的。

  • gpg --gen-key 生成密鑰,生成的時候會做很多選擇,以及添加口令保護私鑰
  • 最後,建議再生成一個撤銷證書,以便以後密鑰作廢時,請求公鑰服務器撤銷你的公鑰:gpg --ken-revoke [用戶ID]
  • gpg --list-keys 列出密鑰 gpg --list-secret-keys私鑰
  • 密鑰服務器是用來發布你的公鑰,並將其分發到其他人的服務器,這樣其他用戶可以輕鬆的根據你數據庫中的名字(或者e-mail地址)來獲取你的公鑰,並給你發送加密信息。避免了把公鑰直接拷貝給其他人 gpg --send-keys [your pubID] --keyserver [keyservers.address.com]
  • gpg --recv-keys [your pubID] --keyserver [keyservers.address.com]從服務器導入本地機器
  • 刪除密鑰:gpg --delete-key [id]
  1. 簽名,驗證完整性gpg -ab temp.java:-b創建一個獨立的簽名文件,-a創建AscII格式輸出,生成temp.java.asc簽名文件,將這兩個文件一起發給用戶,假設用戶已導入你的公鑰
    gpg --verify temp.java.asc 驗證原始文件

  2. 加密

法一:gpg -o encrypted_file.gpg --encrypt -r key-id original.file

命令解釋:

(1)-o encrypted_file.gpg = 指定輸出文件

(2)–encrypt = 做加密

(3)-r = 接收者的KEY-ID,比如這裏就填你朋友的KEY-ID。

(4)original.file = 指定要加密的文件

法二: gpg --recipient [your pubID]--output out.file --encrypt original.file

3. 解密:gpg --decrypt filename.gpg

maven gpg plugin

<plugin>
                       <groupId>org.apache.maven.plugins</groupId>
                       <artifactId>maven-gpg-plugin</artifactId>
                       <version>${maven-gpg-plugin.version}</version>
                       <executions>
                           <execution>
                               <id>sign-artifacts</id>
                               <phase>verify</phase>
                               <goals>
                                   <goal>sign</goal>
                               </goals>
                               <!-- <configuration> <executable>gpg</executable> <homedir>${gpg.homedir}</homedir>
                                   <keyname>${gpg.keyname}</keyname> <passphrase>${gpg.passphrase}</passphrase>
                                   </configuration> -->
                           </execution>
                       </executions>
                   </plugin>

執行mvn clean deploy -Dgpg.passphrase=yourpassphrase

若已經發布了,想簽名,用插件的另一個goal:

mvn gpg:sign-and-deploy-file
> -DpomFile = target/myapp-1.0.pom
> -Dfile = target/myapp-1.0.jar
> -Durl = maven倉庫地址
> -DrepositoryId = id

考慮一個問題:簽名只有正式發佈的時候纔有必要,平常的快照構建是不需要的,profile標籤設置觸發條件

15. 靈活構建:屬性、profile、資源過濾

屬性

  1. 內置
    basedir(pom.xml){basedir}項目的根目錄(包含pom.xml文件的目錄),{version}項目版本

  2. pom屬性,每一個都對應一個pom元素

${project.build.sourceDirectory}:項目的主源碼目錄,默認爲 src/main/java

${project.build.testSourceDirectory}:項目的測試源碼目錄,默認爲 src/test/java

${project.build.directory}:項目構件輸出目錄,默認爲 target/

${project.outputDirectory}:項目主代碼編譯輸出目錄,默認爲 target/classes/

${project.testOutputDirectory}:項目測試代碼編譯輸出目錄,默認爲 target/test-classes/

${project.groupId}:項目的 groupId

${project.artifactId}:項目的 artifactId

project.versionversion{project.version}:項目的 version,與{version}等價

project.build.fianlName{project.build.fianlName}:項目打包輸出文件的名稱。默認爲{project.artifactId}-${project.version}

  1. 自定義屬性

用戶可以在POM的元素下自定義Maven屬性

  1. settings屬性

用戶使用settings.開頭的屬性引用 settings.xml 文件中XML元素的值,如:${settings.localRepository}

  1. java系統屬性:可通過mvn help:system查看

所有Java系統屬性都可以使用Maven屬性引用,${user.home}

  1. 環境變量屬性

所有環境變量都可以使用以env.開頭的Maven屬性引用 ${env.JAVA_HOME}

構建環境的差異

比如開發和測試和發佈所用的數據庫配置都不同!!

我們寫變量值:maven 屬性,然後在某個地方定義它

database.jdbc.driverClass = ${db.driver}

database.jdbc.connectionURL = ${db.url}

database.jdbc.username = ${db.username}

database.jdbc.password = ${db.password}
<profiles>
    <profile>
        <id>dev</id>
        <properties>
            <db.driver>com.mysql.jdbc.Driver</db.driver>
            <db.url>jdbc:mysql://localhost:3360/test</db.url>
            <db.username>username</db.username>
            <db.password>password></db.password>
        </properties>
    </profile>
</profiles>

** 但是,maven默認屬性只在pom中被解析,在資源文件中沒有自動解析,資源文件處理是maven-resource-plugin做的事情,他默認的行爲是將主資源和測試資源文件複製到編譯輸出目錄,這個是在超級pom定義的**
開啓filtering即可

<resources>
    <resource>
        <directory>${project.basedir}/src/main/resources</directory>
        <filtering>true</filtering>
    </resource>
</resources>

<testResources>
    <testResource>
        <directory>${project.basedir}/src/test/resources</directory>
        <filtering>true</filtering>
    </testResource>
<testResources>

然後運行 mvn clean install -Pdev,-P參數表示激活一個profile,構建完成後輸出目錄中的配置就是開發環境的配置了

profile的激活方式

  • 命令行,mvn … -P 加上profile的id,多個的話逗號隔開
  • settings文件中 使某profile一直處於激活
  • 系統屬性激活
  • 操作系統環境激活
  • 文件存在與否激活
  • 默認激活,<activeByDefault>true</activeByDefault>
<profile>  
  <id>dev</id>  
  <activation>  
    <activeByDefault>false</activeByDefault>  
    <jdk>1.5</jdk>  
    <os>  操作系統環境
      <name>Windows XP</name>  
      <family>Windows</family>  
      <arch>x86</arch>  
      <version>5.1.2600</version>  
    </os>  
    <property>  系統屬性 在命令行可以聲明哦 mvn install -Dtest=x
      <name>mavenVersion</name>  
      <value>2.0.5</value>  
    </property>  
    <file>  
      <exists>file2.properties</exists>  
      <missing>file1.properties</missing>  
    </file>  
  </activation>  
  ...  
</profile>  

mvn help:active-profiles 列出當前激活的
mvn help:all-profiles列出當前所有的

  1. pom跟項目一起發佈,所以pom中的profile可修改的元素多
<project>  
    <profiles>  
        <profile>  
            <build>  
                <defaultGoal>...</defaultGoal>  
                <finalName>...</finalName>  
                <resources>...</resources>  
                <testResources>...</testResources>  
                <plugins>...</plugins>  
            </build>  
            <reporting>...</reporting>  
            <modules>...</modules>  
            <dependencies>...</dependencies>  
            <dependencyManagement>...</dependencyManagement>  
            <distributionManagement>...</distributionManagement>  
            <repositories>...</repositories>  
            <pluginRepositories>...</pluginRepositories>  
            <properties>...</properties>  
        </profile>  
    </profiles>  
</project>  
  1. pom外部的profile
<repositories>...</repositories>  
<pluginRepositories>...</pluginRepositories>  
<properties>...</properties>

web資源過濾

在Web項目中,資源文件位於src/main/resources/目錄下,他們經處理後會位於WAR包的WEB-INF/classes目錄下,即這類資源文件在打包過後位於應用程序的classpath中。Web項目中位於src/main/webapp目錄,經打包後位於WAR包的根目錄。這一類資源文件稱作web資源文件,他們在打包過後不位於應用程序的classpath中。web資源默認不會被過濾,因此開啓一般資源文件的過濾也不會影響到web資源文件

<profiles>
    <profile>
        <id>client-a</id>
        <properties>
            <client.logo>a.jpg</client.logo>
            <client.theme>red</client.theme>
        </properties>
    </profile>
    <profile>
        <id>client-b</id>
        <properties>
            <client.logo>b.jpg</client.logo>
            <client.theme>blue</client.theme>
        </properties>
    </profile>
</profiles>

需要配置maven-war-plugin對src/main/webapp這一web資源目錄開啓過濾

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.1-beta-1</version>
    <configuration>
        <webResources>
            <resource>
                <filtering>true</filtering>
                <directory>src/main/webapp</directory>
                <includes>
                    <include>**/*.css</include>
                    <include>**/*.js</include>
                </includes>
            </resource>
        </webResources>
    </configuration>
</plugin>

profile不僅可以用來應對不同的構建環境以保持構建環境的可移植性,還可以用來分離構建的一些較耗時或耗資源的行爲,給予更合適的構建頻率

16. 生成項目站點

添加maven-site-plugin,mvn site,但是多模塊的鏈接點不過去,那麼可以在本地預發佈到一個臨時目錄:
mvn site:stage -DstagingDirectory = D:\temp

  • pom中配置的信息越全,生成的站點信息越豐富
  • 插件maven-project-info-reports-plugin可以配置選擇生成哪些信息報告,maven3配置方法:
<plugin>  
  <groupId>org.apache.maven.plugins</groupId>  
  <artifactId>maven-site-plugin</artifactId>  
  <version>3.0-beta-3</version>  
  <configuration>  
    <reportPlugins>  
      <plugin>  
        <groupId>org.apache.maven.plugins</groupId>  
        <artifactId>maven-project-info-reports-plugin</artifactId>  
        <version>2.4</version>  
        <reports>  
          <report>license</report>  
          <report>mailing-list</report>  
          <report>dependencies</report>  
          <report>dependency-convergence</report>  
          <report>plugin-management</report>  
          <report>cim</report>  
          <report>issue-tracking</report>  
          <report>scm</report>  
          <report>summary</report>  
        </reports>  
      </plugin>  
      <plugin>  
        <groupId>org.apache.maven.plugins</groupId>  
        <artifactId>maven-surefire-report-plugin</artifactId>  
        <version>2.6</version>  
      </plugin>  
      <plugin>  
        <groupId>org.apache.maven.plugins</groupId>  
        <artifactId>maven-javadoc-plugin</artifactId>  
        <version>2.7</version>  
      </plugin>       
      <plugin>  
        <groupId>org.apache.maven.plugins</groupId>  
        <artifactId>maven-checkstyle-plugin</artifactId>  
        <version>2.6</version>  
      </plugin>  
      <plugin>  
        <groupId>org.codehaus.mojo</groupId>  
        <artifactId>jdepend-maven-plugin</artifactId>  
        <version>2.0-beta-2</version>  
      </plugin>  
      <plugin>  
        <groupId>org.codehaus.mojo</groupId>  
        <artifactId>cobertura-maven-plugin</artifactId>  
        <version>2.4</version>  
      </plugin>  
      <plugin>  
        <groupId>org.codehaus.mojo</groupId>  
        <artifactId>taglist-maven-plugin</artifactId>  
        <version>2.4</version>  
      </plugin>  
      <plugin>  
        <groupId>org.apache.maven.plugins</groupId>  
        <artifactId>maven-jxr-plugin</artifactId>  
        <version>2.1</version>  
      </plugin>  
      <plugin>  
        <groupId>org.apache.maven.plugins</groupId>  
        <artifactId>maven-pmd-plugin</artifactId>  
        <version>2.5</version>  
        <configuration>  
          <linkXref>true</linkXref>  
          <minimumTokens>100</minimumTokens>  
          <minimumPriority>3</minimumPriority>                                  
          <targetJdk>1.6</targetJdk>  
        </configuration>  
      </plugin>  
    </reportPlugins>  
  </configuration>  
</plugin>
  • 生成的站點web可以通過xml文件去自定義,修改menu,設置皮膚

17. maven-archetype-plugin

  1. maven archetype:generate,我使用這個命令後出現了很多remote,不止internal,還有dexcloud的local,可以用-DarchetypeCatalog= 來篩選
    來自於catalog,指定本機任一位置的catalog,file://、http協議遠程catalog,http://
  2. 自動化方式,
mvn archetype:generate DarchetypeGroupId=  -DarchetypeArtifactId=maven-archetype-quickstart
 -DarchetypeVersion  -DinteractiveMode=false
-DgroupId=com.mycompany.app -DartifactId=myapp -Dversion=1.0-snap... -Dpackage

生成本地倉庫的catalog

mvn archetype:crawl -Drepository = D:/java/reposiroty -Dcatalog = C:/archetype-catalog.xml

指定要遍歷的倉庫和要更新的文件,不提供會遍歷settings中定義的localRepository,在倉庫根目錄生成archetype-catalog.xml

編寫archetype

  • 自身的pom
  • src/main/resources/archetype-resources/pom.xml基於該模板生成的項目的pom原型,注意在必要的地方使用可配置的屬性代替硬編碼
  • src/main/resources/META-INF/maven/archetype-metadata.xml描述符文件,一聲明哪些目錄和文件應該包含在archetype中,二是這個archetype使用哪些屬性參數
  • src/main/resources/archetype-resources/** 其他需要包含在archetype中的內容
<?xml version="1.0" encoding="UTF-8"?>
<archetype-descriptor name="miuse-job-archetype">
    <fileSets>
        <fileSet filtered="true" encoding="UTF-8">
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.**</include>
            </includes>
        </fileSet>
        <fileSet filtered="true" encoding="UTF-8">
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.xml</include>
                <include>**/**</include>
            </includes>
        </fileSet>
        <fileSet filtered="true" encoding="UTF-8">
            <directory>src/test/java</directory>
            <includes>
                <include>**/*.**</include>
            </includes>
        </fileSet>
  </fileSets>
  <requiredProperties>
    <requiredProperty key="">
      <defaultValue></defaultValue>
    </requiredProperty>
  </requiredProperties>
</archetype-descriptor>

默認要求的參數group artifact version package,還可以要求額外參數,見上述代碼

編寫完成後,clean install 安裝到本地庫
https://blog.csdn.net/lff1991/article/details/76550363

18. 編寫maven插件

  1. 建立一個maven項目,可以用命令行的方式建立如:mvn archetype:generate
    然後選擇:maven-archetype-plugin
  2. pom的特殊之處:
<packaging>maven-plugin</packaging>    maven-plugin-api的依賴
  1. 繼承AbstractMojo類,實現execute方法,提供@goal目標
  2. 提供用戶配置點,@parameter
  3. @parameter expression= 可以從系統屬性讀取字段的值,用戶可以從命令行去配置,也可以在pom中配置
  4. execute方法,可拋出異常MojoExecutionException, MojoFailureException,插件執行時遇到MojoExecutionException會顯示“BUILD ERROR”; MojoFailureException----“BUILD FAILURE”
  5. 日誌對象,getlog().info, getlog().error

Mojo標註

  • @goal <name>插件目標,唯一必須聲明的標註
  • @phase <phase>綁定到生命週期,@phase test
  • @requiredDependencyResolution <scope>運行該Mojo前必須解析所有指定範圍的依賴, compile,test,runtime,默認runtime
  • @requiredProject <true/false>該目標是否必須在一個maven項目中運行,默認爲true
  • @requiredDirectInvocation <true/false>是否只能通過命令行調用,若true,在pom中嘗試綁定到生命週期就報錯,默認false
  • @requiredOnline <true/false>是否要求maven在線,默認false
  • @requiredReport <true/false>是否要求項目報告已生成,默認false
  • @aggregator多模塊項目,該標註表示目標只會在頂層模塊運行
  • @execute goal= "<goal>"運行該目標前,先運行另一目標;如果是本插件的目標,直接使用目標名稱,否則用"prefix:goal"
  • @execute phase= "<phase>"運行該目標前,先讓maven運行一個並行的生命週期,到指定的階段爲止
  • @execute lifecycle= "<lifecycle>" phase="<phase>"運行該目標前,先運行一個自定義的生命週期,到指定的階段爲止。自定義生命週期的配置文件lifecycle.xml

Mojo參數

boolean(boolean和Boolean):

/**

*@parameter

*/

private boolean sampleBoolean:對應配置<sampleBoolean>true</sampleBoolean>

int(Integer,long.Long,short,Short,byte,Byte):

/**

*@parameter

*/

private int sampleInt:對應配置<sampleInt>8</sampleInt>

float(Float,Double,double):

/**

*@parameter

*/

private float sampleFloat:對應配置<sampleFloat>8.2</sampleFloat>

String(StringBuffer,char,Character):

/**

*@parameter

*/

private String sampleString:對應配置<sampleString>heoll</sampleString>

Date(yyyy-MM-dd HH:mm:ss.S a或yyyy-MM-dd HH:mm:ssa):

/**

*@parameter

*/

private Date sampleDate:對應配置<sampleDate>2010-06-09 3:14:55.1 PM或2010-06-09 3:14:55 PM</sampleDate>

File

/**

*@parameter

*/

private File sampleFile:對應配置<sampleFile>c:tem</sampleFile>

URL

/**

*@parameter

*/

private URL sampleUrl:對應配置<sampleUrl>http;//www.baidu.com</sampleUrl>

數組

/**

*@parameter

*/

private String[] includes:對應配置<includes><include>ee</include><include>dd</include></includes>

Collection(任何實現Collection接口的類)

/**

*@parameter

*/

private List includes:對應配置<includes><include>ee</include><include>dd</include></includes>

Map

/**

*@parameter

*/

private Map includes:對應配置<includes><key1>ee</key1><key2>dd</include></key2></includes>

Properties

/**

*@parameter

*/

private Properties includes:對應配置

<includes>

<property>

<name>ee</name>

<value>22</value>

</property>

<property>

<name>dd</name>

<value>11</value>

</property>

</includes>





@parameter額外屬性:

@parameter alias="<aliasName>":爲mojo參數使用別名

@parameter expression="${aSystemProperty}":使用系統屬性表達式對mojo參數進行賦值

@parameter defaultValue="aValue/${anExpression}":提供一個默認值

另外

@readonly:只讀屬性,不允許配置

@required:必需的屬性,未配置,會報錯

插件的集成測試maven-invoker-plugin

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章