# Maven簡介 Maven的本質是一個項目管理工具,將項目開發和管理過程抽象成一個項目對象模型(POM)) 這玩意兒是使用Java開發的,所以採用的就是Java的思想:面向對象 POM (Project Object Model):項目對象模型 Maven的作用: 項目構建:提供標準的、跨平臺的 ...
# Maven簡介
Maven的本質是一個項目管理工具,將項目開發和管理過程抽象成一個項目對象模型(POM))
這玩意兒是使用Java開發的,所以採用的就是Java的思想:面向對象
POM (Project Object Model):項目對象模型
Maven的作用:
- 項目構建:提供標準的、跨平臺的自動化項目構建方式
- 依賴管理:方便快捷的管理項目依賴的資源(jar包),避免資源間的版本衝突問題
- 統一開髮結構:提供標準的、統一的項目結構
下載與安裝:
# Maven基礎概念
倉庫:用於存儲資源,包含各種jar包
倉庫分類:本地倉庫和遠程倉庫(私服和中央倉庫)
坐標:Maven中的坐標用於描述倉庫中資源的位置
坐標的主要組成:
- groupId:定義當前Maven項目隸屬組織名稱(通常是功能變數名稱反寫)
- artifactId:定義當前Maven項目名稱(通常是模塊名稱)
- version:定義當前版本號
- packaging:定義該項目的打包方式
坐標的作用:使用唯一的標識,唯一性定位資源位置,通過該標識可以將資源的識別與下載交由機器完成。
倉庫配置:
- 本地倉庫配置:預設位置與自定義位置
- 遠程倉庫配置:
<repositories>
<repository>
<id>central</id>
<name>Central Repository</name>
<url>https://maven.aliyun.com/repository/central</url>
<layout>default</layout>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
鏡像倉庫配置:阿裡雲Maven鏡像倉庫配置地址
<mirrors>
<mirror>
<!-- 此鏡像的唯一標識符,用來區分不同的mirror元素 -->
<id>nexus-aliyun</id>
<!-- 對那種倉庫進行鏡像(就是替代哪種倉庫)-->
<mirrorOf>central</mirrorOf>
<!-- 鏡像名稱 -->
<name>Nexus aliyun</name>
<!-- 鏡像URL -->
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
</mirrors>
全局setting和用戶setting
- 定義當前電腦中Maven的公共配置,即 mavne安裝目錄/conf/setting.xml
- 定義當前用戶配置,即 配置的本地倉庫地址處有個平級的setting.xml
註:用戶setting和全局setting不一致時,會優先採用用戶setting.xml的配置,因此最好是這二者內容保持一致
# Maven項目
# 手動生成Maven項目
Maven工程目錄結構
Maven項目構建命令:Maven構建命令使用mvn開頭,後面加功能參數,可以一次執行多個命令,使用空格分隔
mvn compile # 編譯
mvn clean # 清理
mvn test # 測試
mvn package # 打包
mvn install # 安裝到本地倉庫
# IDEA生成Maven項目
使用原型創建Maven項目與不使用原型創建Maven項目
例:使用原型創建web項目,選擇archetype-webapp進行項目創建,添加Tomcat插件
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>80</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
# 依賴管理
-
依賴配置:依賴指的是當前項目運行所需要的jar,一個項目可以設置多個依賴。格式:
<!--設置當前項目所依賴的所有jar--> <dependencies> <!--設置具體的依賴--> <dependency> <!--依賴所屬群組id--> <groupId></groupId> <!--依賴所屬項目id--> <artifactId></artifactId> <!--依賴版本號--> <version></version> <!-- <type>pom</type> <scope>import</scope> 只能用在 <dependencyManagement></dependencyManagement> 中 --> <!--類型:jar 則導入jar包 pom 導入的是一個父模塊--> <type></type> <!-- 作用域:import 代表把父模塊中的jar包導入進來 為import時,dependency不參與依賴傳遞 只是把dependency需要的依賴都取過來,像個占位符一樣替換了就行 --> <scope>import</scope> </dependency> </dependencies>
-
依賴傳遞
依賴具有傳遞性,包括直接傳遞和間接傳遞
直接傳遞:在當前項目中通過依賴配置建立的依賴關係(A使用B,A和B就是直接傳遞)
間接傳遞:被依賴的資源如果依賴其他資源,當前項目間接依賴其他資源(比較拗口,意思是如果A依賴B,而B依賴C,那麼A和C之間就是間接傳遞)
依賴傳遞的衝突問題:
- 路徑優先:當依賴中出現相同的資源時,層級越深,優先順序越低,層級越淺,優先順序越高
- 聲明優先:當資源在相同層級被依賴時,配置順序靠前的覆蓋配置順序靠後的
- 特殊優先:當同級配置了相同資源的不同版本,後配置的覆蓋先配置的
- 可選依賴
可選依賴指的是對外隱藏當前所依賴的資源
<dependency>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<!--添加下麵這一行-->
<optional>true</optional>
</dependency>
- 排除依賴
排除依賴指主動斷開依賴的資源,被排除的資源無需指定版本
<dependency>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<exclusions>
<exclusion>
<groupId></groupId>
<artifactId></artifactId>
</exclusion>
</exclusions>
</dependency>
- 依賴範圍
依賴的jar包預設情況可以在任何地方使用,可以通過scope標簽設定其作用範圍
作用範圍:
- 主程式範圍有效(main文件夾範圍內)
- 測試程式範圍有效(test文件夾範圍內)
- 是否參與打包(package文件夾範圍內)
還有兩個:system、import
- import:依賴項替換為指定 POM 的
<dependencyManagement>
中的該依賴項。僅<dependencyManagement>
部分中 pom 類型的依賴項支持此範圍
- 依賴範圍傳遞性:帶有依賴範圍的資源在傳遞時,作用範圍會受到影響
# 生命周期與插件
Maven項目構建生命周期描述的是一次構建過程經歷了多少個事件
Maven對項目構建的生命周期劃分為3套
- clean:清理工作
- default:核心工作,例如編譯、測試、打包、部署等
- site:產生報告,發佈站點等
clean生命周期:
- pre-clean:執行一些需要在clean之前完成的工作
- clean:移除所有上一次構建生成的文件
- post-clean:執行一些需要在clean之後立刻完成的工作
default構建生命周期:compile ——> test-compile ——> test ——> package ——> install
-
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(測試) 使用合適的單元測試框架運行測試(Juint是其中之一)
-
prepare-package(準備打包) 在實際打包之前,執行任何的必要的操作為打包做準備
-
package(打包) 將編譯後的代碼打包成可分發格式的文件,比如JAR、WAR或者EAR文件
-
pre-integration-test(集成測試前) 在執行集成測試前進行必要的動作。比如說,搭建需要的環境
-
integration-test(集成測試) 處理和部署項目到可以運行集成測試環境中
-
post-integration-test(集成測試後) 在執行集成測試完成後進行必要的動作。比如說,清理集成測試環境
-
verify (驗證) 運行任意的檢查來驗證項目包有效且達到質量標準
-
install(安裝) 安裝項目包到本地倉庫,這樣項目包可以用作其他本地項目的依賴
-
deploy(部署) 將最終的項目包複製到遠程倉庫中與其他開發者和項目共用
site生命周期:
-
pre-site 執行一些需要在生成站點文檔之前完成的工作
-
site 生成項目的站點文檔
-
post-site 執行一些需要在生成站點文檔之後完成的工作,並且為部署做準備
-
site-deploy 將生成的站點文檔部署到特定的伺服器上
插件:插件與生命周期內的階段綁定,在執行到對應的生命周期時執行對應的插件功能
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<!--執行插件-->
<executions>
<!--具體怎麼執行-->
<execution>
<!--目標:執行什麼-->
<goals>
<!--執行jar-->
<goal>jar</goal>
</goals>
<!--執行到那個生命周期階段時就要執行該插件 對應前面default中的那些值-->
<phase>generate-test-resources</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
<goal>jar</goal>
值選項:官網:Apache Maven Source Plugin
- source:aggregate aggregrates sources for all modules in an aggregator project.
- source:jar is used to bundle the main sources of the project into a jar archive——對main中源代碼打包
- source:test-jar on the other hand, is used to bundle the test sources of the project into a jar archive——對測試代碼打包
- source:jar-no-fork is similar to jar but does not fork the build lifecycle.
- source:test-jar-no-fork is similar to test-jar but does not fork the build lifecycle.
# 聚合
作用:聚合用於快速構建Maven工程,一次性構建多個項目/模塊
製作方式:創建一個空模塊,打包類型定義為pom
<packaging>pom</packaging>
定義當前模塊進行構建操作時關聯的其他模塊名稱
<modules>
<module>模塊地址</module>
<module>模塊地址</module>
<module>模塊地址</module>
<module>模塊地址</module>
</modules>
註意:參與聚合操作的模塊最終執行順序與模塊間的依賴關係有關,與配置順序無關
# 繼承
作用:通過繼承可以實現在子工程中沿用父工程中的配置(與Java類似)
製作方式:在子工程中生命其父工程坐標與對應的位置
<!--定義該工程的父工程-->
<parent>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<!--填寫父工程的pom文件-->
<relativePath>父工程pom文件地址</relativePath>
</parent>
在父工程中定義依賴管理
<!--聲明此處進行依賴管理-->
<dependencyManagement>
<!--具體的依賴-->
<dependencies>
<dependency>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
</dependency>
</dependencies>
</dependencyManagement>
<!--要管理插件的話,使用如下方式-->
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<!--.....................-->
</plugin>
</plugins>
</pluginManagement>
</build>
繼承依賴使用:在子工程中定義依賴關係,無需聲明依賴版本,版本參照父工程中依賴的版本
<!--子工程使用依賴-->
<dependencies>
<dependency>
<groupId></groupId>
<artifactId></artifactId>
</dependency>
</dependencies>
<!--子工程使用插件-->
<build>
<plugins>
<plugin>
<groupId></groupId>
<artifactId></artifactId>
<!--<version></version>-->
</plugin>
</plugins>
</build>
繼承的資源:
# 繼承與聚合的區別
作用:聚合用於快速構建項目,繼承用於快速配置
相同點:
-
聚合與繼承的pom.xml文件打包方式均為pom,可以將兩種關係製作到同一個pom文件中
-
聚合與繼承均屬於設計型模塊,並無實際的模塊內容
不同點:
-
聚合是在當前模塊中配置關係,聚合可以感知到參與聚合的模塊有哪些
-
繼承是在子模塊中配置關係,父模塊無法感知哪些子模塊繼承了自己
# 屬性
- 自定義屬性
作用:等同於定義變數,方便統一維護
定義格式:
<!--定義自定義屬性-->
<properties>
<spring.version>5.1.9.RELEASE</spring.version>
<junit.version>4.12</junit.version>
</properties>
調用格式:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
- 內置屬性
作用:使用Maven內置屬性,快速配置
調用格式:
${basedir}
${version}
- Setting屬性
作用:使用Maven配置文件setting.xml中的標簽屬性,用於動態配置
調用格式:
${settings.localRepository}
- Java系統屬性
作用:讀取Java系統屬性
調用格式:
${user.home}
系統屬性查詢方式:
mvn help:system
- 環境變數屬性
作用:使用Maven配置文件setting.xml中的標簽屬性,用於動態配置
調用格式:
${env.JAVA_HOME}
環境變數屬性查詢方式:
mvn help:system
# 版本管理
SNAPSHOT(快照版本):
- 項目開發過程中,方便團隊成員合作,解決模塊間相互依賴和實時更新的問題,開發者對每個模塊進行構建的時候,輸出的臨時性版本就叫快照版本(測試階段版本)
- 快照版本會隨著開發的進展不斷更新
RELEASE(發佈版本):
- 項目開發到進入階段里程碑後,向團隊外部發佈較為穩定的版本,這種版本所對應的構建文件是穩定的,即便進行功能的後續開發,也不會改變當前發佈版本的內容,這種版本就叫發佈版本
工程版本號約定:
# 資源配置
配置文件引用pom屬性
作用:在任意配置文件中載入pom文件中定義的屬性
- pom中定義變數:
<properties>
<jdbc.username>root</jdbc.username>
<jdbc.password>zixieqing072413</jdbc.password>
</properties>
- pom中開啟配置文件載入pom屬性
<build>
<!--配置資源文件對應的信息-->
<resources>
<resource>
<!--設定配置文件對應的位置目錄 如 application.yml
支持使用屬性動態設定路徑 如 ${project.basedir}-->
<directory>地址</directory>
<!--開啟對配置文件的資源載入過濾-->
<filtering>true</filtering>
</resource>
</resources>
<!--test配置文件也需要使用時:配置資源文件對應的信息-->
<testResources>
<testResource>
<!--設定配置文件對應的位置目錄 如 application.yml
支持使用屬性動態設定路徑 如 ${project.basedir}-->
<directory>地址</directory>
<!--開啟對配置文件的資源載入過濾-->
<filtering>true</filtering>
</testResource>
</testResources>
</build>
- 在需要使用變數得到配置文件中使用,調用格式:
${地址}
<!--示例-->
${jdbc.username}
# 多環境開發配置
<!--創建多環境-->
<profiles>
<!--定義具體的環境:生產環境-->
<profile>
<!--定義環境對應的唯一名稱 如 prod_env-->
<id>開發環境名稱1</id>
<!--定義環境中的專用的屬性值-->
<properties>
<jdbc.url>jdbc鏈接</jdbc.url>
</properties>
<!--將該套環境設為預設啟動環境-->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<!--定義具體的環境:開發環境 格式同上-->
</profiles>
Maven使用命令啟動那套環境:
mvn 指令 -p 環境定義id
# 示例
mvn install -p prod_env
# 跳過測試
提示
正式開發時,不建議跳過
跳過測試的場景:
- 整體模塊功能未開發
- 模塊中某個功能未開發完畢
- 單個功能更新調試導致其他功能失敗
- 快速打包
- .........................
使用方式:
- 命令的方式
mvn 指令 –D skipTests
# 示例
mvn install –D skipTests
註意
執行的指令生命周期必須包含測試環節
- 使用IDEA界面操作
- 使用pom配置
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
<configuration>
<!-- 設置跳過測試 -->
<skipTests>true</skipTests>
<!-- 包含指定的測試用例 -->
<includes>
<include>**/User*Test.java</include>
</includes>
<!-- 排除指定得到測試用例 -->
<excludes>
<exclude>**/User*TestCase.java</exclude>
</excludes>
</configuration>
</plugin>
# 私服
使用Nexus,是sonatype的產品:
- 下載地址1:https://help.sonatype.com/repomanager3/download
- 下載地址2:https://www.sonatype.com/thanks/repo-oss
啟動伺服器(Windows):
nexus.exe /run nexus
訪問伺服器:預設埠8081,可在其配置文件中修改
http://localhost:8081
修改基礎配置信息:安裝路徑/etc/nexus-default.properties,如預設埠號
修改伺服器運行配置:安裝路徑/bin/nexus.vmoptions,如預設記憶體空間大小
# IDEA中資源上傳和下載
私服倉庫分類:
宿主倉庫(hosted):保存無法從中央倉庫獲取的資源,如
- 自主研發
- 第三方非開源項目
代理倉庫(proxy):代理遠程倉庫,通過Nexus訪問其他公共倉庫
倉庫組(group):
- 將若幹倉庫組成一個群組,簡化配置
- 倉庫組不保存資源,屬於設計型倉庫
私服用戶名密碼:配置在本地倉庫的setting.xml中即可
上傳位置:配置在IDEA中,上傳到私服中的倉庫組不同
下載地址:配置在本地倉庫的setting.xml即可
# 訪問私服配置
- 配置本地倉庫訪問私服許可權(setting.xml)
<servers>
<server>
<!--放release版本的 和nexus中命名保持一致-->
<id>zixq-release</id>
<!--訪問私服的用戶名密碼-->
<username>admin</username>
<password>admin</password>
</server>
<server>
<!--放snapshots版本的-->
<id>zixq-snapshots</id>
<username>admin</username>
<password>admin</password>
</server>
</servers>
- 配置本地倉庫來源(setting.xml)
<!--可以和阿裡雲倉庫同時存在-->
<mirrors>
<mirror>
<id>nexus-zixq</id>
<mirrorOf>*</mirrorOf>
<url>http://localhost:8081/repository/maven-public/</url>
</mirror>
</mirrors>
# IDEA發佈依賴到私服配置
- 配置當前項目訪問私服上傳資源的保存位置(pom.xml)
<distributionManagement>
<repository>
<!--倉庫id,和上面本地倉庫setting.xml中server id保持一致-->
<id>zixq-release</id>
<!--放release版倉庫的url-->
<url>http://localhost:8081/repository/zixq-release/</url>
</repository>
<snapshotRepository>
<id>zixq-snapshots</id>
<url>http://localhost:8081/repository/zixq-snapshots/</url>
</snapshotRepository>
</distributionManagement>
- 發佈資源到私服的命令
mvn deploy
流程:通過IDEA pom中配置的<url>http://localhost:8081/repository/zixq-release/</url>
訪問私服,通過<id>zixq-release</id>
去本地倉庫的setting.xml 的server id找訪問私服的username、password,然後進行發佈
# IDEA插件之Maven Helper
Maven Helper可以解決依賴問題,安裝了Maven Helper插件,只要打開pom文件,就可以打開該pom文件的Dependency Analyzer視圖,並且這個頁面還支持搜索。很方便
進入Dependency Analyzer視圖之後有三個查看選項,分別是:
- Conflicts:衝突
- All Dependencies as List:列表形式查看所有依賴
- All Dependencies as Tree:樹結構查看所有依賴
# jar包衝突說明
解決IDEA中jar包衝突,使用maven的插件:maven helper插件,它能夠給我們羅列出來同一個jar包的不同版本,以及它們的來源,但是對不同jar包中同名的類沒有辦法
# 依賴順序
點擊【All Dependencies as Tree】,查看:從上向下,A依賴於B,B依賴於C
.點擊【Conflicts】,從圖中可以看出有哪些jar存在衝突,存在衝突的情況下最終採用了哪個依賴的版本。標紅的就是衝突版本,白色的是當前的解析版本。這個選項,需要從下向上看
# 解決思路
- 排除指定的版本:如果有兩個依賴的版本發生了衝突,那麼只要用exclusion關鍵字把其中一個依賴給排除掉,只剩下一個依賴即可
-
子工程指定版本號
-
子工程先排除,再指定版本號:如下圖,在starter-web中排除spring-webmvc,然後指定spring-webmvc的版本為6.0.9
-
鎖定版本:使用dependencyManagement統一對依賴的版本進行定義
-
路徑優先:當依賴中出現相同的資源時,層級越深,優先順序越低,層級越淺,優先順序越高。實際使用就是直接在pom中顯示使用且定義版本
-
聲明優先:當資源在相同層級被依賴時,配置順序靠前的覆蓋配置順序靠後的
-
特殊優先:當同級配置了相同資源的不同版本,後配置的覆蓋先配置的
# 對應MD文檔
鏈接:Maven 筆記