Maven入門

来源:https://www.cnblogs.com/wtc1994/archive/2019/03/12/10514281.html
-Advertisement-
Play Games

[TOC] 1. maven的作用 實現依賴管理、構建管理、模塊拆分管理的自動化 參考書籍《Maven in Action》 參考內容:基於中華石杉老師的授課內容整理 2. 依賴管理 2.1 坐標機制 groupId:以公司或者組織的官網的功能變數名稱倒序來開頭 + 項目名。如:com.baidu.oa a ...


目錄

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. 多倉庫架構

14.maven多層倉庫架構

​ 圖 3-1

4. nexus(V3.12)

4.1 常見倉庫介紹

1531695385950

​ 圖 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倉庫架構

16.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。

22_maven生命周期原理

​ 圖6-1

6.1.1 clean生命周期

phase goal
pre-clean 執行清理前的工作
clean 清理上一次構建生成的所有文件
post-clean 執行清理後的工作

6.1.2 default生命周期

default生命周期是最核心的,它包含了構建項目時真正需要執行的所有步驟。

1531760811704

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

1531761221903

​ 圖 6-2

1531761125385

​ 圖 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來聲明依賴和插件的話,會強制子工程全部繼承。

在父工程中使用元素和元素來聲明所有的依賴和插件時,當子工程聲明瞭某個依賴或者插件的groupId+artifactId,但是不指定版本時,就會從父工程繼承那個依賴和插件。

父工程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.版本約束

通過元素用戶可以自定義一個或多個Maven屬性,然後在POM的其他地方使用${屬性名}的方式引用該屬性,這種做法的最大意義在於消除重覆和統一管理。

比如在父工程中:

<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會自動記錄下來每次代碼版本的變更。因為每次提交代碼,相當就是代碼的版本就變更了一次。

35_maven和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,也就是某個時刻的某個版本的代碼。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1. 爬取前的分析 是mitmproxy的命令行介面,比Fiddler、Charles等工具方便的地方是它可以對接Python腳本。 有了它我們可以不用手動截獲和分析HTTP請求和響應,只需寫好 請求和響應 的處理邏輯即可。 它還可以實現數據的解析、存儲等工作,這些過程都可以通過Python實現。 ...
  • 項目右擊 → Build Path → 右側 Add Library → server runtime → Apache Tomcat → Finish → Apply ...
  • 配置文件 Java ...
  • 進位的表示方式 最長見的進位表達形式有,二進位,八進位,十進位,十六進位。他們之間的區別僅體現在標識符的不同。 尾碼區分: B、二進位 H、十六進位 O、八進位 D、十進位 首碼區分: 0x:十六進位(零) 0:八進位(零) 0b:二進位(零) 有錯誤請指出,一起進步,謝謝! ...
  • 前言 語音合成技術能將用戶輸入的文字,轉換成流暢自然的語音輸出,並且可以支持語速、音調、音量設置,打破傳統文字式人機交互的方式,讓人機溝通更自然。 應用場景 將游戲場景中的公告、任務或派單信息通過語音播報,讓玩家玩游戲或配送員送貨的同時,也可接聽新任務。 文學小說類軟體,可以利用百度語音合成技術將文 ...
  • Java8中的Stream Stream使用一種類似用SQL語句從資料庫查詢數據的直觀方式來提供一種對Java集合運算和表達的高階抽象. Stream的特性及優點: 無存儲. Stream不是一種數據結構,它只是某種數據源的一個視圖,數據源可以是一個數組,Java容器或I/O channel等. 為 ...
  • 參考 "Packaging Python Projects" , 源碼在 "nobodxbodon/test package for pypi" : setup.py中 與編寫Visual Studio Code插件初嘗試類似, name只能用英文. 生成發佈包 上傳到測試pypi平臺 測試安裝包. ...
  • 看了一個Beyond的紀錄片, 提到這個. 覺得心有不甘, 於是搜集了24首歌詞, 用Python做了簡單分詞和詞頻統計. 源碼(包括歌詞)在: "program in chinese/study" 統計了總出現次數( )和詞出現在歌曲的數目( ). 前者算進了所有重覆歌詞, 後者是算某個詞出現在了 ...
一周排行
    -Advertisement-
    Play Games
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...
  • 目錄前言PostgreSql安裝測試額外Nuget安裝Person.cs模擬運行Navicate連postgresql解決方案Garnet為什麼要選擇Garnet而不是RedisRedis不再開源Windows版的Redis是由微軟維護的Windows Redis版本老舊,後續可能不再更新Garne ...
  • C#TMS系統代碼-聯表報表學習 領導被裁了之後很快就有人上任了,幾乎是無縫銜接,很難讓我不想到這早就決定好了。我的職責沒有任何變化。感受下來這個系統封裝程度很高,我只要會調用方法就行。這個系統交付之後不會有太多問題,更多應該是做小需求,有大的開發任務應該也是第二期的事,嗯?怎麼感覺我變成運維了?而 ...
  • 我在隨筆《EAV模型(實體-屬性-值)的設計和低代碼的處理方案(1)》中介紹了一些基本的EAV模型設計知識和基於Winform場景下低代碼(或者說無代碼)的一些實現思路,在本篇隨筆中,我們來分析一下這種針對通用業務,且只需定義就能構建業務模塊存儲和界面的解決方案,其中的數據查詢處理的操作。 ...
  • 對某個遠程伺服器啟用和設置NTP服務(Windows系統) 打開註冊表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer 將 Enabled 的值設置為 1,這將啟用NTP伺服器功 ...
  • title: Django信號與擴展:深入理解與實踐 date: 2024/5/15 22:40:52 updated: 2024/5/15 22:40:52 categories: 後端開發 tags: Django 信號 松耦合 觀察者 擴展 安全 性能 第一部分:Django信號基礎 Djan ...
  • 使用xadmin2遇到的問題&解決 環境配置: 使用的模塊版本: 關聯的包 Django 3.2.15 mysqlclient 2.2.4 xadmin 2.0.1 django-crispy-forms >= 1.6.0 django-import-export >= 0.5.1 django-r ...
  • 今天我打算整點兒不一樣的內容,通過之前學習的TransformerMap和LazyMap鏈,想搞點不一樣的,所以我關註了另外一條鏈DefaultedMap鏈,主要調用鏈為: 調用鏈詳細描述: ObjectInputStream.readObject() DefaultedMap.readObject ...
  • 後端應用級開發者該如何擁抱 AI GC?就是在這樣的一個大的浪潮下,我們的傳統的應用級開發者。我們該如何選擇職業或者是如何去快速轉型,跟上這樣的一個行業的一個浪潮? 0 AI金字塔模型 越往上它的整個難度就是職業機會也好,或者說是整個的這個運作也好,它的難度會越大,然後越往下機會就會越多,所以這是一 ...
  • @Autowired是Spring框架提供的註解,@Resource是Java EE 5規範提供的註解。 @Autowired預設按照類型自動裝配,而@Resource預設按照名稱自動裝配。 @Autowired支持@Qualifier註解來指定裝配哪一個具有相同類型的bean,而@Resourc... ...