前言
Maven僅僅是個打包工具而已,個人覺得沒有太大必要花費在打包工具上,這里就列舉一下個人覺得會常用標簽的使用就好了,原理啥的基本就不太會去深度了解了,如果以后遇到需了解Maven工作原理的工作的話,到時候一定分享出來。
pom結構
前面那篇博客已經展示過了,這里就在展示一下,官網上也有文檔可以查看,鏈接:Maven官網pom.xml
parent標簽
這個標簽用的最多是在使用Spring Boot項目以及父子項目的用的最多,
SpringBoot示例:
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.15.RELEASE</version>
</parent>
父子項目示例:
?這里module標簽意思就是該父項目有哪些模塊的意思,值為子模塊的文件夾的名稱,而不是artifactId,不然找不到對應的子模塊,而且在父模塊中的packaging標簽值為pom,表示這是一個父類項目。
坐標
Maven中坐標是Jar包的唯一標識,在pom.xml中指定坐標的標簽元素包括:groupId,artifactId,version,packaging
元素 | 描述 | 說明 |
groupId | 定義當前模塊隸屬的實際Maven項目 | 中小企業常常直接對應公司/組織 |
artifactId | 定義實際項目中的一個模塊 | 唯一標識一個模塊 |
version | 定義當前項目所在的版本 | SNAPSHOT 表示不穩定的版本。 LATEST 指最新發布的版本,可能是個發布版,也可能是一個snapshot版。 RELEASE 指最后一個發布版。 |
packaging | 定義Maven項目打包方式 | 有jar(默認)、war、pom(表示為父模塊)、maven-plugin(當前項目為插件)等. |
classifier | 附屬構件(如javadoc、sources) | 須有附加插件的幫助 |
properties屬性標簽
這個標簽里面可自定義標簽屬性,也可覆蓋默認標簽屬性,示例:
<properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><spring.version>5.1.16.RELEASE</spring.version>
</properties>
....
<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${spring.version}</version></dependency>
</dependencies>
自定義屬性可以在maven的生命周期中使用,最常用的就是在default-resources中使用,用來替換properties文件中的${}值。
Maven自己會有一些內置屬性:
${basedir} 項目根目錄
${project.build.directory} 構建目錄,缺省為target
${project.build.outputDirectory} 構建過程輸出目錄,缺省為target/classes
${project.build.finalName} 產出物名稱,缺省為${project.artifactId}-${project.version}
${project.packaging} 打包類型,缺省為jar
${project.xxx} 當前pom文件的任意節點的內容
dependency依賴標簽
這個標簽下放的就是當前項目依賴jar的坐標。
如果我想引入一下MySQL的驅動包:
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.16</version><scope>compile</scope>
</dependency>
這里有個依賴作用域scope,一般有以下依賴范圍:
- compile:默認范圍,用于編譯,依賴的jar在打包時會包含進去 ? ? ?
- provided:類似于編譯,但支持你期待jdk或者容器提供,類似于classpath,依賴的jar在打包時不會包含進去?
- runtime:在執行時需要使用,依賴的jar在打包時會包含進去
- test:用于test任務時使用,依賴的jar在打包時不會包含進去
- system:需要外在提供相應的元素。通過systemPath來取得,一般該作用域用來引入外部jar包
在使用system作用域的時候,使用systemPath標簽指定外部元素路徑,如:
<systemPath>${project.basedir}/lib/sdk-1.0.jar</systemPath>//項目根路徑下
在依賴標簽里面還有一個標簽屬性optional:該標簽默認值為false指的是父子項目之間的是否傳遞(之前在看Mybatis源代碼的時候,下載下來后的pom.xml里面就會有這個標簽),如果父項目引入一個依賴并且optional標簽設置為true的話,那么子項目打包的時候也會打包進去,如果設置為false的話,那么就不會打包進去。
依賴沖突解決:
在引入依賴的時候會存在一個問題,就是依賴傳遞,如果在項目中引入多個重復的依賴,那么jvm只能拿到一個版本的依賴,其他的版本的依賴就會被拋棄,所以Maven在處理這個上是有一定的順序的,先看一下示例:
如果有個項目pom.xml引入fastjson包的依賴如下:
?則取舍規則如下:
1、路徑最短原則:product和customer里的fastjson引用路徑較短,路徑為兩步 ;pay項目里的fastjson引用路徑較長,路徑為三步。因此pay中的fastjson被淘汰;
2、同路徑長度下,誰先聲明誰優先: product和customer中的fastjson路徑相同,那么就看在pom中是先聲明product還是先聲明customer,誰先用誰的。
profiles標簽
主要應用的場景:開發環境和測試環境的配置是不一致的,為了打包方便,一般我們會將配置文件的寫在一個properties文件中,如下:
在打包的時候指定是測試環境還是開發環境進行不同的打包,實現這樣的一個功能就是使用profiles標簽了,先將兩種不同環境的數據錄入到profiles標簽中,如下所示(activeByDefault為默認配置):
?此定義即指,當mvn命令執行時,我們需要通過加上 -P dev或者-P test方式傳入我們的需要指定的profile的id:dev/test選擇,會導致properties里的變量值含義不同,這個操作需要在build標簽中添加一個資源復制:
dependencyManagement標簽
這個標簽是作為版本號管理使用的,基本上都是用于父項目中,定義好全局統一的版本號,在子項目中就只需要引入groupId以及artifactId了,在SpringBoot的父模塊中就是使用的這個作為統一管理的。
build標簽
該標簽主要是用來打包時做一些處理功能,像資源文件的復制,選擇指定的插件以及最終打包的jar包名稱等。
finalName
當前應用工程打包的jar名稱
pluginManagement標簽
當前標簽和dependencyManagement的作用是一致,在父模塊當中定義好版本號,在子模塊當中直接引用即可
plugin標簽
當前標簽為插件標簽,在上篇博文當中已經提到了Maven生命周期中對應的執行插件有哪些,而插件也是一個jar包,所以引入也是需要通過坐標進行引入的,示例如上。
后面我會發布一篇博客專門講解Maven插件的。
distributionManagement
該標簽是在Maven的deploy階段,即將當前項目推送到遠程私服的倉庫上,以供于他人使用,一般比較大型的公司都會有自己的私服倉庫,公司內部自己也會開發一些組件啥的,開發完之后需推送到公司的私服倉庫當中,私服后面我也會有一片博客講解這個東西,在推送的過程中也可以指定推送哪種類型的倉庫
?還有兩種常用的標簽:repositories和pluginRepositories,用法如下:
repositories:即指定當前項目依賴引入jar使用的倉庫地址,如果在Maven的settings.xml中指定好鏡像倉庫和依賴倉庫后,這里其實是可以不需要指定的,但是如果某些項目需要的依賴倉庫不在settings.xml的配置文件里面,可以在pom.xml中手動指定倉庫。
pluginRepositories:即指定當前項目插件依賴引入jar使用的倉庫地址。功能同上。
mirrors
還有個settings.xml里面的鏡像標簽需要提一下,Maven倉庫鏡像是會攔截所有只想倉庫的路徑,轉向到鏡像當中的倉庫,即如果沒有配置鏡像的話,那么Maven下載依賴包會直接去遠程中央倉庫中下載,而如果配置了鏡像,那么就會被鏡像攔截,轉發到鏡像指定的倉庫下載依賴,和鏡像標簽一起使用的還有mirrorOf標簽,該標簽是可以指定哪些倉庫可以被鏡像攔截
<!--匹配所有倉庫請求,即將所有的倉庫請求都轉到該鏡像上-->
<mirrorOf>*</mirrorOf> <!--將倉庫jcenter和repo2的請求轉到該鏡像上,使用逗號分隔多個遠程倉庫。 -->
<mirrorOf>jcenter,repo1</mirrorOf> <!--匹配所有倉庫請求,jcenter除外,使用感嘆號將倉庫從匹配中排除。-->
<mirrorOf>*,!jcenter</miiroOf> <!-- settings.xml中的倉庫 -->
<repository><id>jcenter</id><url>https://jcenter.bintray.comt</url>
</repository>
<repository><id>repo1</id><url>https://repo1.maven.org/maven2</url>
</repository>
下面列舉一些鏡像地址:
<!-- 阿里云的鏡像站--><mirror><id>nexus-aliyun</id><name>Nexus aliyun</name><url>http://maven.aliyun.com/nexus/content/groups/public/</url> <mirrorOf>central</mirrorOf>
</mirror>
<!-- maven官方運維倉庫 -->
<mirror> <id>repo2</id> <name>Mirror from Maven Repo2</name> <url>http://repo2.maven.org/maven2/</url> <mirrorOf>central</mirrorOf>
</mirror>
<!-- maven在UK架設的倉庫-->
<mirror> <id>ui</id> <name>Mirror from UK</name> <url>http://uk.maven.org/maven2/</url> <mirrorOf>central</mirrorOf>
</mirror>
<!-- JBoss的倉庫 -->
<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>
Maven不僅僅是以上的那些標簽屬性,在此只是列出來個人覺得平常使用的比較多的標簽。