上次說到我在工做中是這樣使用Git,已是1個月前的故事了,時間啊,就這樣慢慢流逝了。java
此次來講說maven
這玩意,一樣仍是那句話,maven對我而言只是工具,一些常規操做已經足夠了,有空有興趣纔會去深刻研究它。接下來會記錄下本身使用maven時須要注意
和理解
的地方,至於那些基本概念和環境配置的問題,相信你們都懂。linux
maven倉庫可分爲本地倉庫
和遠程倉庫
。web
若是公司本身有搭建maven私服,那麼還能夠細分爲本地倉庫
、私服倉庫(內網)
、中央倉庫(外網)
。spring
私服是指公司內網搭建的maven倉庫,可供公司內部人員使用。數據庫
pom.xml裏依賴jar包的尋找流程:apache
本地倉庫找
,找到直接用,不須要聯網。
私服倉庫找
,找到就下載到本地,以供下次直接使用。
中央倉庫找
,而後下載到私服、本地,以供下次直接使用。
沒私服的話,本地倉庫找不到就直接去中央倉庫找。json
maven構建過程的各個環節,表明maven工做的某個階段api
舊的class字節碼文件刪除
,爲下一次編譯作準備。
編譯成class字節碼
。
自動調用junit程序
。
打war包
,java工程
打jar包
。
複製到倉庫中指定位置
。
拷貝最終的工程包到遠程倉庫
,以供其餘開發人員使用。
maven實際工做時,順序不必定從上到下。幾個階段是重要階段,並非maven的所有階段。具體執行什麼階段,執行順序是啥,依賴於它的生命週期。tomcat
有些文章會說到最後一個構建階段:部署->將動態Web工程生成的war包複製到Servlet容器的指定目錄下,使其運行。 這須要在tomcat這種servlet容器配置點什麼,而後再執行maven相關命令,war包就會自動部署到容器下。不過我如今開發基本都是在SpringBoot環境下,war包部署就不存在了。有興趣再去熟悉熟悉。服務器
三套相互獨立
的生命週期,互不影響,定義了構建環節的執行順序
。
清理工做
。
經常使用且核心
,包括編譯、測試、打包、安裝、發佈等
依賴上述的構建過程和生命週期,maven執行任何一個階段的時候,它前面的全部階段都會執行
。
例如咱們執行 mvn install 的時候,代碼會被編譯,測試,打包。但不會clean(清理),由於install和clean是在不一樣的生命週期裏,但咱們能夠結合使用,如:mvn clean install
idea內置maven界面也說明這一點,點擊生命週期的某一個階段,maven會把前面到此階段都執行下,不信你能夠試試。
除了經過idea的界面操做maven,咱們也能夠手打命令,否則在linux系統上你怎麼搞?
執行maven構建命令,必須在pom.xml所在的目錄
根據maven生命週期,當你執行mvn install時, compile、test、package、intall會依次執行,mvn deploy同理。
實際開發中,我都是直接敲命令編譯打包安裝,用得最多的是
mvn clean install -Dmaven.test.skip=true -U
加上clean是先把文件清理乾淨,100%確保install後是最新修改的文件。
若是當前項目並不須要被任何其餘項目依賴,就不必install了,執行mvn clean package便可
mvn命令支持帶參數
maven倉庫除了保存jar包,還有插件。核心程序僅定義了抽象的生命週期,具體工做仍是得由特定的插件來完成。
通常我使用maven-compiler-plugin 插件來編譯,定義的jdk版本必定要跟你開發使用的jdk版本一致,否則後續打包會出錯等各類奇怪問題。
pom.xml的build節點裏
<build>
<plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build> 複製代碼
標識jar包能被管理的範圍。
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.3</version> <scope>compile</scope> </dependency> 複製代碼
compile:依賴項目參與編譯、測試、部署運行
test:僅參與測試,包括測試代碼的編譯、運行
provided:能夠參與編譯、測試,但打包不會引入
一張表格來總結
compile | test | provided | |
---|---|---|---|
主程序 | ✓ | × | ✓ |
測試程序 | ✓ | ✓ | ✓ |
參與部署 | ✓ | × | × |
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.3</version> <scope>system</scope> <systemPath>../xx/xx.jar</systemPath> </dependency> 複製代碼
注意:非compile的依賴不能傳遞!
packaging節點裏
<groupId>com.goku</groupId> <artifactId>goku-manage</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> 複製代碼
聚合工程裏有多個pom.xml
父工程經過modules聚合子工程,該工程執行maven命令時,2個子工程也會執行
<modules> <module>goku-user</module> <module>goku-order</module> </modules> 複製代碼
子工程經過parent標籤繼承父工程,可直接引用父工程的配置項
<parent> <groupId>com.goku</groupId> <artifactId>goku-manage</artifactId> <version>1.0-SNAPSHOT</version> </parent> 複製代碼
至於聚合模塊的好處有不少,真真切切讓我感覺到的有其二
聚合工程裏,版本號能夠統一配置,統一管理。同個公司的不一樣項目,全部依賴包版本最好相同。
有些公司會單獨建一個工程,只用來統一版本號,打包成pom形式,給公司內部各個項目繼承。
頂層父工程的pom文件裏的properties節點
<properties> <java.version>1.8</java.version> <plugin.jdk.version>1.8</plugin.jdk.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <spring-boot.version>2.1.3.RELEASE</spring-boot.version> <fasterjson.version>1.2.12</fasterjson.version> </properties> 複製代碼
dependency的vesion引用配置好的版本號
<dependency>
<groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${spring-boot.version}</version> </dependency> 複製代碼
dependencyManagement統一管理版本
請注意<scope>import</scope>
<dependencyManagement>
<dependencies> <dependency> <!-- Import dependency management from Spring Boot --> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.0.0.RELEASE</version> <type>pom</type> <!--導入spring-boot-dependencies裏的配置,必定程度上解決了單繼承問題。--> <scope>import</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fasterjson.version}</version> </dependency> </dependencies> </dependencyManagement> 複製代碼
說明:
項目打包時區分環境,其實是根據不一樣環境生成不一樣的配置文件。
通常區分本地、開發/測試、線上。
pom.xml裏的build和profiles(如下配置僅針對SpringBoot的yml文件)
<build>
<!-- 打包後文件名稱:項目名-環境-版本 --> <finalName>${project.artifactId}</finalName> <resources> <resource> <directory>src/main/resources</directory> <!-- 開啓過濾替換功能--> <filtering>true</filtering> <includes> <!-- 項目打包完成的包中只包含當前環境文件 --> <include>application.yml</include> <include>application-${profileActive}.yml</include> <include>**/*.xml</include> <include>**/*.properties</include> </includes> </resource> </resources> </build> <!-- 多環境配置方案 --> <profiles> <profile> <id>local</id> <properties> <profileActive>local</profileActive> </properties> <activation> <!-- 默認狀況下使用本地開發配置 如 打包時不包含 -p 參數--> <activeByDefault>true</activeByDefault> </activation> </profile> <!-- 打包命令package -P test --> <profile> <id>test</id> <properties> <profileActive>test</profileActive> </properties> </profile> <!-- 打包命令package -P prod --> <profile> <id>prod</id> <properties> <profileActive>prod</profileActive> </properties> </profile> </profiles> 複製代碼
maven命令帶參數-P,如:mvn clean install -P test
項目打包後只保留application.yml、ymlapplication-test.yml
application.yml裏的@profileActive@也會被替換成test
最終打包生成的文件
指定本地倉庫地址,不配置就放在默認路徑${user.home}/.m2/repository
<localRepository>D:\develop\maven\Repmaven</localRepository>
複製代碼
公司搭建了maven私服,上傳下載須要認證,就須要配置。
NOTE: You should either specify username/password OR privateKey/passphrase, since these pairings are used together.
可配置帳號密碼 或 私鑰形式,支持多個server
<servers> <server> <!--id須要與repository或mirror中的id相對應--> <id>server01</id> <username>admin</username> <password>SwaDmin159</password> </server> <server> <id>server02</id> <privateKey>/xxx/.ssh/id_dsa</privateKey> <passphrase>some_passphrase</passphrase> <filePermissions>664</filePermissions> <directoryPermissions>775</directoryPermissions> <configuration></configuration> </server> </servers> 複製代碼
倉庫鏡像,中央倉庫的代理,若是配置了鏡像,就直接去鏡像中下載依賴。它至關於一個攔截器,攔截maven對默認中央倉庫的請求,把請求裏的遠程倉庫地址,重定向到mirror裏配置的地址。
<mirrors> <mirror> <id>nexus-aliyun</id> <mirrorOf>central</mirrorOf> <name>Nexus aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public</url> </mirror> </mirrors> 複製代碼
全部項目使用私服倉庫,可在setting.xml配置,profile節點配置repositories,最後再激活profile。
固然,私服裏不僅一個倉庫,可配置多個repository。
<profile> <repositories> <repository> <!-- id須要與私服裏倉庫的id對應 --> <id>public</id> <name>public</name> <url>http://xxx.com/nexus/content/groups/public/</url> <layout>default</layout> </repository> </repositories> </profile> <activeProfiles> <activeProfile>public</activeProfile> </activeProfiles> 複製代碼
若只想針對某個項目,則在當前項目的pom.xml配置私服,repositories節點下配置便可
<repositories>
<repository> <!-- id須要與私服裏倉庫的id對應 --> <id>public</id> <name>public</name> <url>http://xxx.com/nexus/content/groups/public/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories> 複製代碼
有時咱們本身開發的模塊須要被其餘部門的開發人員使用,就須要發佈到私服。
執行mvn deploy前,需配置distributionManagement。
快照版本跟發佈版本分別存儲到不一樣倉庫地址。
<distributionManagement> <repository> <id>release</id> <name>Project Release</name> <url>http://xxx.com/nexus/content/groups/release/</url> </repository> <snapshotRepository> <id>snapshots</id> <name>Project SNAPSHOTS</name> <url>http://xxx.com/nexus/content/groups/snapshot/</url> </snapshotRepository> </distributionManagement> 複製代碼
maven會根據jar包的版本號(version節點)是否帶有-SNAPSHOT來判斷是快照版本仍是正式版本。沒有SNAPSHOT都認爲是快照版本。
快照版本 :1.0.0-SNAPSHOT
發佈版本 :1.5.3.RELEASE
若是是快照版本,在mvn deploy時會自動發佈到快照版本庫中,覆蓋老的快照版本,後面使用快照版本模塊時,在不更改版本號的狀況下,直接編譯打包時,maven會自動從遠程服務器上下載最新的快照版本。
若是是正式發佈版本,在mvn deploy時會自動發佈到正式版本庫中,後面使用正式版本的模塊,在不更改版本號的狀況下,編譯打包時若是本地已經存在該版本的模塊則不會主動去遠程服務器上下載。
這個也容易理解,快照版本通常定義爲不穩定版本,須要實時更新。
若以爲此文對你有幫助,麻煩點個小贊,這對我將是最大的鼓勵!
微信搜悟空Java
或掃碼關注悟空公衆號,一塊兒學習一塊兒進步!