[TOC] 1. maven的作用 實現依賴管理、構建管理、模塊拆分管理的自動化 參考書籍《Maven in Action》 參考內容:基於中華石杉老師的授課內容整理 2. 依賴管理 2.1 坐標機制 groupId:以公司或者組織的官網的功能變數名稱倒序來開頭 + 項目名。如:com.baidu.oa a ...
目錄
- 1. maven的作用
- 2. 依賴管理
- 3. 多倉庫架構
- 4. nexus(V3.12)
- 5. 部署項目到私服
- 6. 生命周期
- 7. 插件
- 8. 工程聚合
- 9.繼承
- 10.版本約束
- 11.使用import強制約束依賴方的版本號
- 12.版本管理與版本控制
1. maven的作用
實現依賴管理、構建管理、模塊拆分管理的自動化
參考書籍《Maven in Action》
參考內容:基於中華石杉老師的授課內容整理
2. 依賴管理
2.1 坐標機制
- groupId:以公司或者組織的官網的功能變數名稱倒序來開頭 + 項目名。如:com.baidu.oa
- artifactId:項目中的某個模塊,或者某個服務(主流)。如oa-auth服務。
- version:工程的版本號
- packaging:工程的打包方式。一般是war和jar兩種方式。
classifier:定義某個工程的附屬項目。幾乎不用。
坐標的意義:通過五個維度的坐標可以唯一定位一個項目的發佈包
2.2 版本管理
version:1.0.0-SNAPSHOT版本
- 第一位是大版本。通常在整體架構有特別的升級或者變化時才會累加第一位大版本。
- 第二位是小版本,一般如果加入一些新的功能或者模塊,或者做了一些重構,就會累加第二位小版本。
- 第三位是最小版本,一般如果是修複一些bug,或者作出輕微的改動,就會累加第三位小版本。
- SNAPSHOT:就是當前這個版本下的快照版本,代表代碼正在開發或者測試中,可以試用,但是沒有經過完善測試,不會承諾非常穩定。如果沒有SNAPSHOT,那麼就是說已經經過完善測試,是可以發佈的穩定版本。
2.3 依賴範圍
maven有三套classpath。classpath就是項目中用到的各種依賴的類,jvm在運行的時候需要去classpath下麵載入對應的類。
maven在編譯源代碼的時候有一套classpath;在編譯測試代碼以及執行測試代碼的時候有一套classpath;運行項目的時候有一套classpath;依賴範圍就是用來控制依賴包與這三種classpath的關係的。
簡單來說,不同的依賴範圍,會導致那個依賴包可能在編譯、測試或者打包運行的時候,有時候可以使用,有時候不能夠使用
- compile:編譯依賴範圍,在編譯,測試,運行時都需要。
- test: 測試依賴範圍,測試時需要。編譯和運行不需要。如Junit
- runtime: 運行時依賴範圍,測試和運行時需要。編譯不需要。如JDBC驅動包
- provided:已提供依賴範圍,編譯和測試時需要。運行時不需要。如servlet-api
- system:系統依賴範圍。本地依賴,不在maven中央倉庫。
2.4 依賴傳遞
1級依賴 \二級依賴 | compile | test | provided | runtime |
---|---|---|---|---|
compile | compile | - | - | runtime |
test | test | - | - | test |
provided | provided | - | provided | provided |
runtime | runtime | - | - | runtime |
舉例1:junit的依賴範圍是test,junit對A的依賴範圍是compile,那麼項目對A的依賴是test。
舉例2:項目依賴於A,A是compile;A依賴於B,B是test;則項目對B的依賴範圍是空。
2.5 依賴衝突的調節
Maven會自動依賴調解,即對已給項目不同的版本選擇一個版本來使用。
Maven對依賴衝突採取的調節方式是最短路徑原則和第一聲明原則。
A->B->C->X(1.0)
A->D->X(2.0)
由於只能引入一個版本的包,此時Maven按照最短路徑選擇導入x(2.0)
A->B->X(1.0)
A->D->X(2.0)
路徑長度一致,那麼哪個依賴在pom.xml里先聲明,maven就採用哪個。
2.6 可選依賴
<optional>true</optional>
此時依賴傳遞失效,不會向上傳遞。很少使用。
如果A依賴於B,B依賴於C,B對C的依賴是optional,那麼A就不會依賴於C。
反之,如果沒有optional,根據傳遞性依賴機制,A會依賴於C。
2.7 排除依賴
場景再現
X -> A -> C-1.0
X -> B -> D -> C-2.0
根據2大依賴原則,此時項目會採用1.0版本的C。如果D調用了2.0版本C中新的方法,此時由於項目中依賴的是1.0版本的C,該版本還沒有此方法,那麼項目就會報錯。
顯然,根據軟體的相容性,通常是引入最新版的依賴。此時,需要手動控制maven的依賴傳遞。
使用mvn dependency:tree進行依賴分析,此時的依賴路徑樹如下。
A
--C-1.0
B
--D
--C-2.0
使用exclusion將A中的1.0版本所依賴的C給排除掉,即可解決問題
<dependency>
<groupId>A</groupId>
<artifactId>A</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>C</groupId>
<artifactId>C</artifactId>
</exclusion>
</exclusions>
</dependency>
此時的依賴樹如下:
A
B
--D
--C-2.0
3. 多倉庫架構
圖 3-1
4. nexus(V3.12)
4.1 常見倉庫介紹
圖 4-1
hosted:宿主倉庫。這個倉庫是用來讓你把你公司內部的發佈包部署到這個倉庫里來,然後公司內的其他人就可以從這個宿主倉庫里下載依賴去使用。
proxy:代理倉庫。代理了公司外部的中央倉庫,國內目前流行的是阿裡雲鏡像倉庫,由阿裡雲去連接中央倉庫。
group:倉庫組。其實就是將各種宿主倉庫、代理倉庫全部組成一個虛擬的倉庫組,然後項目只要配置依賴於一個倉庫組,該項目就可以自動連接倉庫組對應的各種倉庫。
maven-central:maven中央倉庫的代理倉庫。
maven-releases:該倉庫是個宿主倉庫。用於部署公司內部的release版本的發佈包(類似於1.0.0,release的意思就是你的工程已經經過了完善的測試,如單元測試,集成測試,QA測試,上生產環境使用了)到這個倉庫裡面,供其他同事在生產環境依賴和使用。
maven-snapshots:該倉庫是個宿主倉庫,用於部署公司內部的snapshot版本的發佈包到這個倉庫里(如果你的某個工程還在開發過程中,測試還沒結束,但是,此時公司里其他同事也在開發一些工程,需要依賴你的包進行開發和測試,聯調,此時你的工程的版本就是類似1.0.0-SNAPSHOT這樣的版本),供其他同事在開發和測試的時候使用。
3rd party:該倉庫是個宿主倉庫,主要用來部署沒法從公共倉庫獲取的第三方依賴包。比如說,你的項目依賴於第三方支付廠商的一個依賴包,但是那個依賴包不是開源的,是商業的包。那麼你是沒有辦法從maven中央倉庫獲取的。此時,可能會自己手動從支付廠商那裡獲取到一個jar包,下載之後上傳到私服里來,就放這個倉庫里。該倉庫需要手動創建。
maven-public:倉庫組。上面所有release倉庫都在這個倉庫組內
4.2 nexus倉庫架構
圖4-2
4.3 nexus的使用
4.3.1 激活profile
有了私服後就需要將公司中的項目配置為強制從公司內的私服來下載,不允許走外網。這樣可以統一管理。畢竟nexus私服本身也是代理了各種中央倉庫,直接用nexus私服就可以了。
通常會在settings.xml配置文件中,為當前機器統一配置使用的私服倉庫地址,而且一般都是直接用私服中的倉庫組,在settings.xml中用profiles即可。
<profiles>
<profile>
<id>nexus</id>
<repositories>
<repository>
<id>nexus</id>
<name>Nexus </name>
<url>http://localhost:8081/nexus/content/groups/public</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>nexus</id>
<name>Nexus Plugin Repository</name>
<url>http://localhost:8081/nexus/content/groups/public</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>nexus</activeProfile>
</activeProfiles>
激活對應的profile,在項目執行構建的時候,就會將profile中的倉庫配置應用到每個項目中去。
4.3.2 配置mirror
用mirror鏡像機制,來強制要求所有對遠程倉庫的請求,全部通過鏡像走私服。
<mirrors>
<mirror>
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<url>http://localhost:8081/nexus/content/groups/public</url>
</mirror>
</mirros>
將所有repository的id修改為central,直接覆蓋maven超級pom中的morning中央倉庫,相當於此時唯一的遠程中央倉庫變成了我們自己配置的兩個倉庫。
然後將url配置全部改為http://central,其實是沒意義的一個url,因為此時在需要從遠程倉庫下載依賴或者插件的時候,會從兩個自己配置的central倉庫去走,然後看release或者snapshot是否支持,如果支持,那麼就會找鏡像配置,由於設置了鏡像匹配所有請求,所以所有請求都會走鏡像,而鏡像配置的是私服地址,所以相當於所有的請求都會走私服了。
4.3.3 許可權管理
nexus私服預設就是可以讀的,不需要認證,公司區域網內的人都可以去配置之後拉取依賴。但是如果要進行部署的話,需要有一個專用的部署賬號,通過賬號認證,才能部署發佈包到nexus私服。
nexus的許可權使用的是經典的RBAC模型,預設有三個用戶:
- admin:管理員賬號。預設密碼是admin123
- deployment:開發賬號。可以進行搜索和部署構建。3版本後已經被消除掉了。
- anonymous:匿名賬號。沒有給認證信息的賬號,只能查看依賴。
5. 部署項目到私服
5.1 發佈倉庫配置
在pox.xml中設置
<distributionManagement>
<repository>
<id> nexus-releases</id>
<name> Nexus Release Repository</name>
<url>http://localhost:8081/nexus/content/repositories/releases/</url>
</repository>
<snapshotRepository>
<id> nexus-snapshots</id>
<name> Nexus Snapshot Repository</name>
<url>http://localhost:8081/nexus/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
5.2 部署專業賬號的配置
由於匿名用戶只能下載依賴,不能部署發佈包,因此如果要能夠部署發佈包,還需要在settings.xml文件里通過
<servers>
<server>
<id>nexus-releases</id>
<username>deployment</username>
<password>deployment123</password>
</server>
<server>
<id>nexus-snapshots</id>
<username>deployment</username>
<password>deployment123</password>
</server>
</servers>
5.3 自動部署
mvn clean deploy
執行此命令後,maven會自動編譯源代碼、運行單元測試、打成jar包、將jar包安裝到本地倉庫、將jar包部署到配置的遠程私服倉庫裡面去。(清理、編譯、測試、打包、安裝、部署)。
5.4 手動部署
有些第三方廠商的jar包,比如特殊資料庫廠商的jdbc驅動,或者某個廠商的支付相關的api jar包,是不提供公網下載的,只能從他們那裡拿到一個jar包,此時就需要手動將其上傳到3rd party倉庫裡面去。
比如:fastdfs_client_v1.24.jar
手動部署:
mvn deploy:deploy-file -DgroupId=com.csource -DartifactId=fastdfs-client-java -Dversion=1.24 -Dpackaging=jar
-Dfile=F:\DevelopmentKit\fastdfs_client_v1.24.jar
-Durl=http://localhost:8081/repository/3rd-party/
-DrepositoryId=nexus-3rd-party
6. 生命周期
一個完整的項目構建過程通常包括清理、編譯、測試、打包、集成測試、驗證、部署等步驟,Maven從中抽取了一套完善的、易擴展的生命周期。Maven的生命周期是抽象的,其中的具體任務都交由插件來完成。Maven為大多數構建任務編寫並綁定了預設的插件,如針對編譯的插件:maven-compiler-plugin。用戶也可自行配置或編寫插件。
6.1 三套生命周期
aven有三套完全獨立的生命周期,clean,default和site。每套生命周期都可以獨立運行,每個生命周期的運行都會包含多個phase(階段),每個phase又是由各種插件的goal來完成的,一個插件的goal可以認為是一個功能。每次執行一個生命周期,都會依次執行這個生命周期內部的多個phase,每個phase執行時都會執行某個插件的goal完成具體的功能。且後面的phase依賴於前面的phase。執行某個phase時,其前面的phase會依順序執行,但不會觸發另外兩套生命周期中的任何phase。
圖6-1
6.1.1 clean生命周期
phase | goal |
---|---|
pre-clean | 執行清理前的工作 |
clean | 清理上一次構建生成的所有文件 |
post-clean | 執行清理後的工作 |
6.1.2 default生命周期
default生命周期是最核心的,它包含了構建項目時真正需要執行的所有步驟。
6.1.3 site生命周期
phase | goal |
---|---|
pre-site | |
site | 生成項目的站點文檔 |
post-site | |
site-deploy | 發佈生成的站點文檔 |
註意,maven會從上到下執行每個pharse的plugin goal。如果該階段沒有綁定任務plugin,該階段將什麼都不執行。
6.2 不執行生命周期
但是有些命令是不執行任何一個生命周期的任何一個phase。而是直接執行指定的插件的一個goal。如:
mvn dependency:tree ---> 直接執行dependency這個插件的tree這個goal
mvn deploy:deploy-file ---> 直接執行deploy這個插件的deploy-file這個goal
7. 插件
http://maven.apache.org/plugins/index.html
由於maven在執行過程中會執行生命周期中的各種phase,通過在pom.xml中配置想要的插件,將某個第三方插件綁定到某個階段的phase。此後插件就會執行其goal,實現想要的功能。
7.1 插件和goal
圖 6-2
圖 6-3
7.2 自定義綁定
用戶可以根據需要將任何插件目標綁定到任何生命周期的階段,如:將maven-source-plugin的jar-no-fork目標綁定到default生命周期的package階段,這樣,以後在執行mvn package命令打包項目時,在package階段之後會執行源代碼打包,生成如:ehcache-core-2.5.0-sources.jar形式的源碼包。
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.1</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>verify</phase> <!-- 要綁定到的生命周期的階段 -->
<goals>
<goal>jar-no-fork</goal> <!-- 要綁定的插件的目標 -->
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
7.3 配置插件
Maven插件高度易擴展,可以方便的進行自定義配置。如:配置maven-compiler-plugin插件編譯源代碼的JDK版本為1.7:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
也可以對插件的各個目標進行更具體的配置。Configuring Plug-ins
7.4 插件倉庫
跟其他構件一樣,插件也是根據坐標存儲在Maven倉庫中。超級POM中Maven配置的預設插件遠程倉庫如下:
<pluginRepositories>
<pluginRepository>
<id>central</id>
<name>Central Repository</name>
<url>http://repo.maven.apache.org/maven2</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
<releases>
<updatePolicy>never</updatePolicy>
</releases>
</pluginRepository>
</pluginRepositories>
8. 工程聚合
8.1 提出問題
假設有三個模塊:組織機構,許可權管理,流程審批,且這三個模塊都是一個人在開發,那麼勢必會有一些場景,比如說是三個模塊互相之間有一些依賴,然後呢,其中一個被依賴的基礎模塊修改了代碼,這個時候,我們要幹嘛?
(1)要運行一下基礎模塊的單元測試套件,確保所有單元測試都可以通過
(2)要將修改代碼後的模塊部署到本地倉庫
(3)其他模塊要依賴更新版本的snapshot包,
(4)需要運行其他所有依賴這個基礎模塊的模塊的單元測試套件,確保依賴它的其他模塊沒有任何問題
那如果是20個工程呢?顯然這樣處理是不合理的。
8.2 解決方案
maven的解決方案是提供聚合功能。通過設定一個父工程,在父工程里聚合這些子工程。只要對父模塊運行一次構建命令,maven就會自動對這個父模塊下麵的所有子模塊都運行相應的構建命令,這樣就可以保證一鍵自動化構建所有的模塊,而無需一個一個依次去構建。
<groupId>com.xxx.oa</groupId>
<artifactId>oa-parent</artifactId> <!-- 通常父工程以parent結尾 -->
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging> <!-- 註意是個pom項目 -->
<name>oa parent project</name>
<modules>
<module>oa-organ</module> <!-- 聚合的子項目 -->
<module>oa-auth</module>
<module>oa-flow</module>
</modules>
一般來說會將模塊統一放在父工程的目錄下,然後對oa-parent運行mvn clean install,此時就會對oa-parent中所有的工程都進行統一的構建。
9.繼承
9.1 繼承
通常對同一個系統,需要將各個模塊的工程,其中的基礎性的、相同的依賴,全部放入一個父工程中,集中式統一約束所有模塊的依賴,避免每個模塊負責的人胡亂使用依賴版本,比如有的人用spring 3,有的人用spring 4。
maven裡面提供了一個繼承功能,即可以將一個項目中所有模塊通用的一些配置,比如依賴和插件,全部放在一個父工程中,然後子工程可以選擇從父工程中要繼承的依賴和插件。此時子工程只要聲明groupId和artifactId即可,不需要聲明version版本號,因為version全部放在父工程中統一聲明,強制約束所有子工程的相同依賴的版本要一樣。
9.2 實現方式
在父工程中,直接用dependencies和plugins來聲明依賴和插件的話,會強制子工程全部繼承。
在父工程中使用
父工程oa-parent
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<version>${org.eclipse.persistence.jpa.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>${javaee-api.version}</version>
</dependency>
<dependcy>
....
</depency>
</dependencies>
</dependencyManagement>
子模塊
<!--繼承父類-->
<parent>
<artifactId>oa-parent</artifactId>
<groupId>com.xxx.oa</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>oa-organ</artifactId>
<packaging>jar</packaging>
<!--依賴關係-->
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
10.版本約束
通過
比如在父工程中:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xxx.oa</groupId>
<artifactId>oa-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>oa parent project</name>
<url>http://maven.apache.org</url>
<modules>
<!-- 模塊都寫在此處 -->
<module>oa-auth</module>
<module>oa-persist</module>
<module>oa-another</module>
</modules>
<properties>
<!-- 定義 spring版本號 -->
<spring.version>4.0.2.RELEASE</spring.version>
<junit.version>4.7</junit.version>
</properties>
<!-- 配置共有依賴 -->
<dependencyManagement>
<dependencies>
<!-- spring 依賴 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- junit 依賴 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
以後每次修改,比如升級spring版本時,就直接修改父工程的properties元素就可以了,所有的子工程會保持一致
11.使用import強制約束依賴方的版本號
11.1 提出問題
比如你基於activiti開發了一個流程審批的封裝組件,這是一個不屬於任何一個項目的基礎的一個組件。其他人如果要用你的這個組件,肯定會在depedencies裡面去定義和聲明。但是,假設依賴方依賴了你的組件,你的組件依賴了activiti 1.3版本,而依賴方自己又聲明瞭一個對activiti 1.2的依賴,此時根據依賴調解的原則,肯定是用他自己的舊版本。這就會造成依賴衝突。
11.2 解決方案
所以說,對於公司里一些重量級的組件,一般來說會採取下麵的這種方式:
- 首先自己開發一個工程,那個工程是對外提供服務的
- 接著再開發一個pom包,尾碼名為bom。這個pom包中用
元素聲明好對你的組件的依賴的版本號,還有你的組件使用的重要的第三方開源框架的版本號 - 依賴方依賴於那個工程的pom類型的包,再在dependency裡面去聲明自己要的依賴,此時版本就被約束了
依賴方
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.zhss.commons</groupId>
<artifactId>commons-flow-bom</artifactId>
<version>1.2.9</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
此時,假設依賴方要自己依賴一個過舊的開源框架的版本,就會有提示報警,不讓他自行定義過舊版本的框架。
12.版本管理與版本控制
12.1 兩者的區別
版本管理:通常指的是maven中的version,項目的版本管理,隨著整個功能的開發,bug的修複,或者大的架構升級,通常來說,都會增加版本號。
版本控制:代碼版本控制,git中的多次提交,每次往git代碼倉庫提交一次代碼,這個代碼的版本就變更了一次,而git會自動記錄下來每次代碼版本的變更。因為每次提交代碼,相當就是代碼的版本就變更了一次。
12.2 maven中的版本管理
12.2.1 版本的類別
版本分為兩種,一種是快照(snapshot)版本,一種是發佈(release)版本
快照版本就是版本號後面加上SNAPSHOT,比如1.0.0-SNAPSHOT
發佈版本就是版本號上不加SNAPSHOT的,比如1.0.0
12.2.2 常見的版本迭代規則
版本通常而言是三位的。比如1.0.0
1.0.0中的第一個1指的是一個重大版本,比如已經基本成型的一個系統架構。
也有不少項目一開始是0.0.1這樣的版本,這個指的就是這個系統剛開始起步,甚至都沒能形成一個完整的東西出來,只是少數核心功能也出來了。
比如,用springboot開發的電商系統,一開始1.0.0這個版本包含了商城首頁、購物車、訂單系統、物流系統,就這麼幾個模塊。如果某天改造和升級到微服務架構,把核心的幾個模塊改造了spring cloud的微服務化。那麼版本就變為了2.0.0。大版本的變更很少見,一般幾年才一次。
1.0.0中的第二個0指的是一個次要版本,比如1.1.0,那麼就是加了一些新的功能或者開發了一些新的模塊,或者做了一些較大的代碼重構,技術升級改造。
比如,新增一個用戶評論功能,此時就會進入一個版本,叫做1.1.0-SNAPSHOT,在內部先開發和測試。接著發佈1.1.0版本,此時這個版本就新增了一個用戶評論的模塊。
次要版本的變更一般就是對應各種需求,比如一個持續幾周,或者一個月或者了幾個月的大需求,對應一個次要版本
1.0.0中的第三個0指的是日常迭代的一個增量版本,比如1.1.1,一般對應著修複了一個bug,或者對某些代碼做了輕微的優化或者調整。
比如,突然發現購物車這塊有個bug,修複這個bug後版本號就是1.1.1-SNAPSHOT,這個bug的修複在內部先開發和測試,讓產品經理來驗收。最後發佈,此時版本變成了1.1.1。此時代碼就是包含了一個bug的修複。
增量版本一般就是一個大需求中的多個小需求,每個小需求可以給一個增量版本,或者是緊急fix了一個bug,那麼就增加一個增量版本。
12.2.3 其他常見的命名版本
1)beta版本
maven的標準版本規範里,還包含了一個1.0.0-beta-1。
這裡的beta代表的是公開測試版,就是對外提供試用的。
最後一個1代表的是增量版本的一個裡程碑,就是在進行某個bug修複,或者功能調整的時候,是分為多個步驟,也就是多個裡程碑的,那麼此時可能就會對應了1.1.1-beta-1,1.1.1-beta-2,1.1.1-beta-3,這樣好幾個裡程碑版本,每個裡程碑版本代表完成了一個小階段。
2)alpha版本
alpha也可以理解為實驗版本,也就是內部測試版本,就是給自己公司內部用的。
3)rc版本
預發佈版本,基本就比較穩定了,但是還不是最終發佈版,可以嘗試下載使用了。
12.3 從SNAPSHOT到RELEASE
通常,在開發的時候,版本都是SNAPSHOT版本。
如果要將snapshot發佈發佈為release版本,至少需要滿足幾個條件:
(1)所有的單元測試全部通過
(2)pom.xml中沒有任何snapshot版本的依賴
(3)pom.xml中沒有任何snapshot版本的插件
(4)這個版本的代碼已經全部提交到對應的git分支上了,同時一定從分支merge到了master主幹分支上去,並且給master分支打上了一個tag,這個tag就是對主幹分支這一時刻代碼的一個標簽,這樣任何時候都可以回退到主幹分支的任何一個tag對應的版本的代碼上去
此時一個release版本就完成了,然後就繼續升級到下一個版本的snapshot版本上去,繼續進行開發和測試。
12.4 版本與主幹、分支以及標簽
通常情況下一個版本對應一個分支,會在分支中進行各種開發+測試,搞定之後就會merge到主幹。
然後就會給這個時候的主幹打一個tag作為主幹在這個版本的代碼,以後任何時候都可以使用主幹的某個tag,也就是某個時刻的某個版本的代碼。