一篇文章帶你搞定JAVA Maven
1、maven是什么,為什么存在?項目結(jié)構(gòu)是什么樣子,怎么定位jar
官方網(wǎng)站說了好多,整的多復(fù)雜一樣,簡單說:maven是一個管理包的工具。
Maven 存在的必要性是什么吶?想想開源的jar包如此之多,版本又如此之多,在沒有Maven之前,我們管理jar包全部都是下載之后創(chuàng)建一個lib的文件夾,然后項目進行引用,在其他的項目成員需要修改一個jar的時候需要到處拷貝,在部署的時候也很麻煩,問題存在就要解決,因此出現(xiàn)了Maven,統(tǒng)一管理,統(tǒng)一的倉庫,只需要配置是要哪個版本的包,直接下載就夠了,不用拷貝,是不是很方便。
現(xiàn)在大的問題解決了,怎么定位一個jar包吶?
2、Idea 的操作
1.新建maven項目
File ->新建->project
勾選從原型(模板)創(chuàng)建,選擇maven-archetype-qiuckstart
填入項目的名字,和groupId (公司域名反過來,如com.alibaba)
選擇本地倉庫的位置,和自定義的setting配置
一路finish,然后等待idea 創(chuàng)建模板項目就好了。
2.配置倉庫
Maven 倉庫有三種類型:
- 本地(local)
- 中央(central)
- 遠程(remote)
當我們執(zhí)行 Maven 構(gòu)建命令時,Maven 開始按照以下順序查找依賴的庫:
步驟 1 - 在本地倉庫中搜索,如果找不到,執(zhí)行步驟 2,如果找到了則執(zhí)行其他操作。
步驟 2 - 在中央倉庫中搜索,如果找不到,并且有一個或多個遠程倉庫已經(jīng)設(shè)置,則執(zhí)行步驟 4,如果找到了則下載到本地倉庫中以備將來引用。
步驟 3 - 如果遠程倉庫沒有被設(shè)置,Maven 將簡單的停滯處理并拋出錯誤(無法找到依賴的文件)。
步驟 4 - 在一個或多個遠程倉庫中搜索依賴的文件,如果找到則下載到本地倉庫以備將來引用,否則 Maven 將停止處理并拋出錯誤(無法找到依賴的文件)。
阿里云倉庫配置:
<repositories> <repository> <id>central</id> <name>aliyun maven</name> <url>https://maven.aliyun.com/repository/public/</url> <layout>default</layout> <!-- 是否開啟發(fā)布版構(gòu)件下載 --> <releases> <enabled>true</enabled> </releases> <!-- 是否開啟快照版構(gòu)件下載 --> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories>
3.添加依賴,添加fastjson的依賴
舉個例子:
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> </dependency>
4.打包項目
3、Maven坐標主要組成
- groupId:組織標識(包名),一般常用公司域名的反序,比如com.alibaba
- artifactId:項目名稱,項目的具體名稱
- version:項目的當前版本 ,一般版本號為 大版本.小版本.小版本序號
- packaging:項目的打包方式,最為常見的jar和war兩種
4、maven生命周期
4.1 名詞解釋
lifecycle:生命周期,這是maven最高級別的的控制單元,它是一系列的phase組成,也就是說,一個生命周期,就是一個大任務(wù)的總稱,不管它里面分成多少個子任務(wù),反正就是運行一個lifecycle,就是交待了一個任務(wù),運行完后,就得到了一個結(jié)果,中間的過程,是phase完成的,自己可以定義自己的lifecycle,包含自己想要的phase
phase:可以理解為任務(wù)單元,lifecycle是總?cè)蝿?wù),phase就是總?cè)蝿?wù)分出來的一個個子任務(wù),但是這些子任務(wù)是被規(guī)格化的,它可以同時被多個lifecycle所包含,一個lifecycle可以包含任意個phase,phase的執(zhí)行是按順序的,一個phase可以綁定很多個goal,至少為一個,沒有g(shù)oal的phase是沒有意義的
goal: 這是執(zhí)行任務(wù)的最小單元,它可以綁定到任意個phase中,一個phase有一個或多個goal,goal也是按順序執(zhí)行的,一個phase被執(zhí)行時,綁定到phase里的goal會按綁定的時間被順序執(zhí)行,不管phase己經(jīng)綁定了多少個goal,你自己定義的goal都可以繼續(xù)綁到phase中
mojo: lifecycle與phase與goal都是概念上的東西,mojo才是做具體事情的,可以簡單理解mojo為goal的實現(xiàn)類,它繼承于AbstractMojo,有一個execute方法,goal等的定義都是通過在mojo里定義一些注釋的anotation來實現(xiàn)的,maven會在打包時,自動根據(jù)這些anotation生成一些xml文件,放在plugin的jar包里
可以通俗理解為lifecyle 是一個公司,phrase 是具體的部門,goal 是一個項目,Mojo 是項目內(nèi)部的人,其他的都是管理層級,具體的執(zhí)行還是人。
4.2 生命周期
4.3 goal 的概念
一個goal是獨立的,它可以被綁定到多個phase中去,也可以一個phase都沒有。如果一個goal沒有被綁定到任何一個lifecycle,它仍然可以直接被調(diào)用,而不是被lifecycle調(diào)用。
因此可以這樣理解phase與goal的關(guān)系:
1.phase其實就是goal的容器。實際被執(zhí)行的都是goal。phase被執(zhí)行時,實際執(zhí)行的都是被綁定到該phase的goal。
2.goal與goal之間是獨立的。因此單獨執(zhí)行一個goal不會導(dǎo)致其他goal被執(zhí)行。
goal可以通俗理解為一個項目。
4.4 生命周期和phase的關(guān)系
clean生命周期每套生命周期都由一組階段(Phase)組成,我們平時在命令行輸入的命令總會對應(yīng)于一個特定的階段。比如,運行mvn clean ,這個的clean是Clean生命周期的一個階段。有Clean生命周期,也有clean階段。Clean生命周期一共包含了三個階段:
1.pre-clean 執(zhí)行一些需要在clean之前完成的工作
2.clean 移除所有上一次構(gòu)建生成的文件
3.post-clean 執(zhí)行一些需要在clean之后立刻完成的工作
"mvn clean" 中的clean就是上面的clean,在一個生命周期中,運行某個階段的時候,它之前的所有階段都會被運行,也就是說,"mvn clean"等同于 mvn pre-clean clean ,如果我們運行 mvn post-clean ,那么 pre-clean,clean 都會被運行。這是Maven很重要的一個規(guī)則,可以大大簡化命令行的輸入
執(zhí)行phase實際執(zhí)行的是goal。如果一個phase沒有綁定goal,那這個phase就不會被執(zhí)行。
<plugin> <groupId>com.mycompany.example</groupId> <artifactId>display-maven-plugin</artifactId> <version>1.0</version> <executions> <execution> <phase>process-test-resources</phase> <goals> <goal>time</goal> </goals> </execution> </executions> </plugin>
一個生命周期包含一些列的步驟,當執(zhí)行生命周期的時候,會把所有的步驟執(zhí)行一次
官方文檔:
http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
http://maven.apache.org/ref/3.3.9/maven-core/lifecycles.html
5、idea maven的配置
POM 中可以指定以下配置:
- 項目依賴 dependencies
- 插件 plugins
- 執(zhí)行目標
- 項目構(gòu)建 profile
- 項目版本
- 項目開發(fā)者列表
- 相關(guān)郵件列表信息
6、POM有2個很重要的關(guān)系:聚合、繼承
一、聚合
如果我們想一次構(gòu)建多個項目模塊,那我們就需要對多個項目模塊進行聚合
1.聚合配置代碼
<modules> <module>模塊一</module> <module>模塊二</module> <module>模塊三</module> </modules>
例如:對項目的Hello、HelloFriend、MakeFriends這三個模塊進行聚合
<modules> <module>../Hello</module> <module>../HelloFriend</module> <module>../MakeFriends</module> </modules>
其中module的路徑為相對路徑。
二、繼承
繼承為了消除重復(fù)的配置,我們把很多相同的配置提取出來,例如:grouptId,version,相同的依賴包等。
繼承配置代碼:
<parent> <groupId>me.gacl.maven</groupId> <artifactId>ParentProject</artifactId> <version>0.0.1-SNAPSHOT</version> <relativePath>../ParentProject/pom.xml</relativePath> </parent>
Idea 中可以新建一個maven項目,然后刪光文件夾,只留一個pom.xml,然后添加模塊,選擇繼承。
7、Maven 中的 profile
- Maven 中有一個概念叫做:profile,它主要是為了解決不同環(huán)境所需的不同變量、配置等問題。比如我們內(nèi)網(wǎng)開發(fā)的數(shù)據(jù)庫配置,端口配置等是和生產(chǎn)環(huán)境不同的,這個時候就需要區(qū)分。
- 有了 profile,可以根據(jù)激活的條件,啟動不同條件下的配置信息。
- profile 是可以有多個的,也可以同時激活多個 profile,方便自由組合。
<profiles> <profile> <!--不同環(huán)境Profile的唯一id--> <!--開發(fā)環(huán)境--> <id>dev</id> <properties> <!--profiles.active是自定義的字段(名字隨便起),自定義字段可以有多個--> <profiles.active>dev</profiles.active> </properties> </profile> <profile> <!--線上環(huán)境--> <id>prod</id> <properties> <profiles.active>prod</profiles.active> </properties> <activation> <activeByDefault>true</activeByDefault> </activation> </profile> </profiles>
Idea 中會顯示配置的兩個profile ,可以選擇激活
pom文件里的配置為
<build> <resources> <resource> <directory>src/main/resources/</directory> <!--先排除掉兩個文件夾--> <excludes> <exclude>dev/*</exclude> <exclude>prod/*</exclude> </excludes> <includes> <!--如果有其他定義通用文件,需要包含進來--> <!--<include>messages/*</include>--> </includes> </resource> <resource> <!--這里是關(guān)鍵!根據(jù)不同的環(huán)境,把對應(yīng)文件夾里的配置文件打包--> <directory>src/main/resources/${profiles.active}</directory> </resource> </resources> </build> <profiles> <profile> <!--不同環(huán)境Profile的唯一id--> <!--開發(fā)環(huán)境--> <id>dev</id> <properties> <!--profiles.active是自定義的字段(名字隨便起),自定義字段可以有多個--> <profiles.active>dev</profiles.active> </properties> </profile> <profile> <!--線上環(huán)境--> <id>prod</id> <properties> <profiles.active>prod</profiles.active> </properties> <activation> <activeByDefault>true</activeByDefault> </activation> </profile> </profiles>
8、maven 插件
Maven的核心僅僅定義了抽象的生命周期,具體的任務(wù)都是交由插件完成的。
每個插件都能實現(xiàn)多個功能,每個功能就是一個插件目標goal。
Maven的生命周期與插件目標相互綁定,以完成某個具體的構(gòu)建任務(wù),例如compile就是插件maven-compiler-plugin的一個插件目標。
常用插件:
maven-antrun-plugin maven-archetype-plugin maven-assembly-plugin maven-dependency-plugin maven-enforcer-plugin maven-help-plugin maven-release-plugin maven-resources-plugin maven-surefire-plugin build-helper-maven-plugin exec-maven-plugin jetty-maven-plugin versions-maven-plugin
9、環(huán)境變量
${basedir}
表示項目根目錄,即包含pom.xml文件的目錄;
${version}
表示項目版本;
${project.basedir}
同${basedir};
${project.baseUri}
表示項目文件地址;
${maven.build.timestamp}
表示項目構(gòu)件開始時間;
${maven.build.timestamp.format}
表示屬性${maven.build.timestamp}
的展示格式,默認值為yyyyMMdd-HHmm,可自定義其格式,其類型可參考java.text.SimpleDateFormat。
${project.build.directory}
表示主源碼路徑;
${project.build.sourceEncoding}
表示主源碼的編碼格式;
${project.build.sourceDirectory}
表示主源碼路徑;
${project.build.finalName}
表示輸出文件名稱;
${project.version}
表示項目版本,與${version}相同;
${project.xxx}
當前pom文件的任意節(jié)點的內(nèi)容
${env.xxx}
獲取系統(tǒng)環(huán)境變量。
${settings.xxx}
指代了settings.xml中對應(yīng)元素的值。
10、Maven 依賴沖突的2個方法
1.統(tǒng)一版本
使用dependencyManagement 進行版本鎖定,dependencyManagement可以統(tǒng)一管理項目的版本號,確保應(yīng)用的各個項目的依賴和版本一致。
如果我們項目中只想使用spring core 5.2.0的包,pom.xml可以改為如下
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.2.0.RELEASE</version> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.7.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.2.0.RELEASE</version> </dependency> </dependencies>
2.排除依賴
依賴查找的兩個原則:
使用路徑近者優(yōu)先原則:直接依賴級別高于傳遞依賴。
使用第一聲明者優(yōu)先原則:誰先定義的就用誰的傳遞依賴,即在pom.xml文件自上而下,先聲明的jar坐標,就先引用該jar的傳遞依賴。
Idea 可以安裝maven helper插件,解決沖突。
maven helper插件安裝成功,點開pom.xml會發(fā)現(xiàn)多了一個Dependency Analyzer視圖,如下上面按鈕的圖標含義如下
Conflicts(查看沖突)
All Dependencies as List(列表形式查看所有依賴)
All Dependencies as Tree(樹形式查看所有依賴)
上圖說明有3個jar存在沖突,點擊沖突的jar,可以查看和哪個jar產(chǎn)生沖突,如下圖
點開pom.xml,切換到Dependency Analyzer視圖,選擇All Dependencies as Tree,點擊要排除的jar,右鍵會出現(xiàn)Execlude選項,如下
11、scope
scope取值 | 有效范圍(compile, runtime, test) | 依賴傳遞 | 例子 |
---|---|---|---|
compile | all | 是 | spring-core |
provided | compile, test | 否 | servlet-api |
runtime | runtime, test | 是 | JDBC驅(qū)動 |
test | test | 否 | JUnit |
system | compile, test | 是 |
compile :為默認的依賴有效范圍。如果在定義依賴關(guān)系的時候,沒有明確指定依賴有效范圍的話,則默認采用該依賴有效范圍。此種依賴,在編譯、運行、測試時均有效。
provided :在編譯、測試時有效,但是在運行時無效。例如:servlet-api,運行項目時,容器已經(jīng)提供,就不需要Maven重復(fù)地引入一遍了。
runtime :在運行、測試時有效,但是在編譯代碼時無效。例如:JDBC驅(qū)動實現(xiàn),項目代碼編譯只需要JDK提供的JDBC接口,只有在測試或運行項目時才需要實現(xiàn)上述接口的具體JDBC驅(qū)動。
test :只在測試時有效,例如:JUnit。
system :在編譯、測試時有效,但是在運行時無效。和provided的區(qū)別是,使用system范圍的依賴時必須通過systemPath元素顯式地指定依賴文件的路徑。由于此類依賴不是通過Maven倉庫解析的,而且往往與本機系統(tǒng)綁定,可能造成構(gòu)建的不可移植,因此應(yīng)該謹慎使用。systemPath元素可以引用環(huán)境變量。
總結(jié):
Maven是開發(fā)中常用的工具,很重要,所以盡可能的掌握。
本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
Maven?Pom?文件中的隱式依賴導(dǎo)致Jar沖突問題
這篇文章主要介紹了Maven?Pom?文件中的隱式依賴導(dǎo)致Jar沖突問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12深入學(xué)習(xí)java位運算的基礎(chǔ)知識
位運算是直接對整數(shù)在內(nèi)存中的二進制位進行操作嗎,位運算即可以節(jié)約內(nèi)存,同時使程序速度更快效率更高。文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,下面我們來一起學(xué)習(xí)下吧2019-06-06使用springmvc運行流程分析,手寫spring框架嘗試
這篇文章主要介紹了使用springmvc運行流程分析,手寫spring框架嘗試,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10Spring MVC Mybatis多數(shù)據(jù)源的使用實例解析
項目需要從其他網(wǎng)站獲取數(shù)據(jù),因為是臨時加的需求,這篇文章主要介紹了Spring MVC Mybatis多數(shù)據(jù)源的使用實例解析,需要的朋友可以參考下2016-12-12