Maven基礎知識大梳理
Maven工程基礎知識
maven 工程中不直接將 jar 包導入到工程中,而是通過在 pom.xml 文件中添加所需 jar包的坐標,這樣就很好的避免瞭 jar 直接引入進來,在需要用到 jar 包的時候,隻要查找 pom.xml 文件,再通過 pom.xml 文件中的坐標,到一個專門用於”存放 jar 包的倉庫”(maven 倉庫)中根據坐標從而找到這些 jar 包,再把這些 jar 包拿去運行。
為瞭解決這個過程中速度慢的問題,maven 中也有索引的概念,通過建立索引,可以大大提高加載 jar 包的速度
Maven倉庫的分類
本地倉庫 :用來存儲從遠程倉庫或中央倉庫下載的插件和 jar 包,項目使用一些插件或 jar 包,優先從本地倉庫查找
遠程倉庫:如果本地需要插件或者 jar 包,本地倉庫沒有,默認去遠程倉庫下載(私服)。
中央倉庫:在 maven 軟件中內置一個遠程倉庫地址https://www.mvnrepository.com/ ,它是中央倉庫,服務於整個互聯網。
Maven常用命令的含義
compile:編譯— compile 是 maven 工程的編譯命令,作用是將 src/main/java 下的文件編譯為 class 文件輸出到 target目錄下。
clean:清理— clean 是 maven 工程的清理命令,執行 clean 會刪除 target 目錄及內容。
test:測試— test 是 maven 工程的測試命令 mvn test,會執行 src/test/java 下的單元測試類。
package:打包—package 是 maven 工程的打包命令,對於 java 工程執行 package 打成 jar 包,對於 web 工程打成 war包。
install:安裝— install 是 maven 工程的安裝命令,執行 install 將 maven 打成 jar 包或 war 包發佈到本地倉庫
一個項目生命周期
打包類型:<packaging >
jar:執行 package 會打成 jar 包
war:執行 package 會打成 war 包
pom :用於 maven 工程的繼承,通常父工程設置為 pom
依賴范圍:<scope>
A 依賴 B,需要在 A 的 pom.xml 文件中添加 B 的坐標,添加坐標時需要指定依賴范圍,依賴范圍包括:
compile:compile指 A 在編譯時依賴 B,此范圍為默認依賴范圍。編譯范圍的依賴會用在編譯、測試、運行,由於運行時需要所以編譯范圍的依賴會被打包。
provided:provided 依賴隻有在當 JDK 或者一個容器已提供該依賴之後才使用, provided 依賴在編譯和測試時需要,在運行時不需要,比如:servlet api 被 tomcat 容器提供。
runtime:runtime 依賴在運行和測試系統的時候需要,但在編譯的時候不需要。比如:jdbc的驅動包。由於運行時需要所以 runtime 范圍的依賴會被打包。
test:test 范圍依賴 在編譯和運行時都不需要,它們隻有在測試編譯和測試運行階段可用,比如:junit。由於運行時不需要所以 test范圍依賴不會被打包。
system:system 范圍依賴與 provided 類似,但是你必須顯式的提供一個對於本地系統中 JAR文件的路徑,需要指定 systemPath 磁盤路徑,system依賴不推薦使用。
依賴范圍由強到弱的順序是:compile>provided>runtime>test
pom文件中常用標簽的含義
<?xml version="1.0" encoding="UTF-8"?> <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> <!--聲明項目描述符遵循哪一個POM模型版本。4.0.0--> <groupId>com.tfjybj</groupId> <artifactId>super</artifactId> <packaging>pom</packaging> <version>1.0.0-SNAPSHOT</version> <!--項目的名稱, Maven產生的文檔用--> <name>super</name> <!-- 項目的詳細描述, Maven 產生的文檔用。--> <description>super</description> <!--聚合 來管理同個項目中的其他模塊--> <modules> <module>super-common</module> <module>super-gateway</module> <module>super-zipkin</module> <module>super-provider</module> <module>super-provider-api</module> </modules> <!--繼承 說明這是一個boot工程--> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.8.RELEASE</version> </parent> <!--統一管理jar包版本--> <properties> <!--項目編碼方式,maven編譯版本--> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <!--統一管理jar包版本--> <spring.cloud.version>2.1.0.RELEASE</spring.cloud.version> <spring.boot.version>2.1.8.RELEASE</spring.boot.version> <mysql.version>6.0.6</mysql.version> </properties> <!--統一管理版本號--> <!--在父工程pom文件中聲明依賴,但不引入,父項目聲明,供子項目按需引入--> <dependencyManagement> <dependencies> <!-- nacos服務註冊/發現--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>${spring.cloud.version}</version> <!--排除ribbon的依賴--> <exclusions> <exclusion> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </exclusion> </exclusions> </dependency> <!--nacos配置中心來做配置管理--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <version>${spring.cloud.version}</version> </dependency> <!--mysql--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> <!-- mysql依賴的作用范圍--> <scope>runtime</scope> </dependency> </dependencies> </dependencyManagement> <!--所有聲明在父項目 dependencies 中的依賴都會自動引入,並默認被所有子項目繼承--> <!--即使在子項目中不引入該依賴,那麼子項目依然會從父項目中繼承該依賴項。--> <dependencies> </dependencies> <!--發現依賴和擴展的遠程倉庫列表 --> <!--遠程倉庫列表,它是Maven用來填充本地倉庫所使用的一組遠程項目。 --> <repositories> <!--包含需要連接到遠程倉庫的信息--> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> </repository> </repositories> <!--用於項目打包,打包需要的插件--> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
聚合與繼承的關系
1、聚合主要是為瞭方便快速構建項目,繼承主要是為瞭消除重復配置
2、對於聚合模塊而言,它知道有哪些被聚合的模塊,但那些被聚合的模塊不知道這個聚合模塊的存在;對於繼承的父pom 而言,它不知道有哪些子模塊繼承它,但那些子模塊都必須知道自己的父pom 是什麼
3、聚合pom 與繼承中的父pom 的 packaging 都必須是 pom;同時,聚合模塊與繼承中的父模塊除瞭 pom 外,都沒有實際的內容
依賴沖突
Maven的依賴機制會導致Jar包的沖突。
舉個例子,現在你的項目中,使用瞭兩個Jar包,分別是A和B。現在A需要依賴另一個Jar包C,B也需要依賴C。但是A依賴的C的版本是1.0,B依賴的C的版本是2.0。這時候,Maven會將這1.0的C和2.0的C都下載到你的項目中,這樣你的項目中就存在瞭不同版本的C,這時Maven會依據依賴路徑最短優先原則,來決定使用哪個版本的Jar包,而另一個無用的Jar包則未被使用,這就是所謂的依賴沖突。
依賴調節原則
1.第一聲明者優先原則:
在pom文件定義依賴,以先聲明的依賴為準。
誰先在pom.xml中申明,就用誰的。跟坐標代碼的順序有關
2.路徑近者優先原則:
以上兩個jar包都依賴瞭spring-beans。
spring-context和spring-webmvc都會傳遞過來spring-beans,那如果直接把spring-beans的依賴寫在pom文件中,那麼項目就不會再使用其他依賴傳遞過來的spring-beans。
因為自己直接在pom中定義spring-beans要比其他依賴傳遞過來的路徑要近。
3.排除依賴原則:
使用Maven中的<exclusions>標簽,例如
<!--使用的openfeign--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>2.2.1.RELEASE</version> <exclusions> <exclusion> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </exclusion> </exclusions> </dependency>
4.鎖定版本原則:
面對眾多的依賴,有一種方法不用考慮依賴路徑、聲明優化等因素可以采用直接鎖定版本的方法確定依賴構件的版本,版本鎖定後則不考慮依賴的聲明順序或依賴的路徑,以鎖定的版本的為準添加到工程中,此方法在企業開發中常用。
解決依賴沖突-使用MavenHelper
在idea中下載插件mavenHelper解決依賴沖突,使用步驟看圖
找到沖突,點擊右鍵,然後選擇Exclude即可排除沖突版本的Jar包。
以上就是Maven基礎知識大梳理的詳細內容,更多關於Maven基礎知識的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- java maven進階教學
- Maven依賴中scope的含義
- 關於pom.xml中maven無法下載springcloud包問題
- spring-boot-maven-plugin報紅解決方案(親測有效)
- SpringCloud學習筆記之SpringCloud搭建父工程的過程圖解