maven教程(一)定義與背景
maven的本質是一個跨平臺的專案管理工具
它主要有兩個功能:構建與依賴管理
(一)構建
構建是什麼,以“java原始檔”,“框架配置檔案”,“JSP”,“HTML”,“圖片”等資源為原材料去生產一個可以執行的專案的過程
以java語言為例,如果我們沒有這些工具,我們就需要手動進行以下操作
- 編譯
編譯我們自己寫的原始碼.java檔案,形成.class檔案。使用javac命令。
javac Hello.java
如果我們原始碼中使用到了第三方程式碼,就需要-classpath加入對應的jar包進去
javac -cp tom.jar Hello.java
- 執行
使用java命令執行,也需要引入使用到的第三方jar包
Java -classpath .;/home/wangke/tom.jar com.hello.wangke.Hello
執行java命令的時候,實際就是啟動了一個虛擬機器,系統提供了三種類載入器:
Ø 啟動類載入器(Bootstrap ClassLoader),負責將存放在<JAVA_HOME>\lib目錄中的,或者被-Xbootclasspath引數所指定的路徑中的,並且是JVM識別的jar包(僅按照檔名識別,如rt.jar,如果名字不符合,即使放在lib目錄中也不會被載入),載入到虛擬機器記憶體中
Ø 擴充套件類載入器,負責載入<JAVA_HOME>\lib\ext目錄中的,或者被java.ext.dirs系統變數所指定的路徑中的所有類庫
Ø 應用程式類載入器(Application ClassLoader),負責載入使用者類路徑(
我們就要手動保證我們用到的所有類都能成功正確的被載入進來
- 打包
打包為jar包、war包等
jar -cvfm hello.jar META-INF\MANIFEST.MF Hello.class Tom.class
該命令表示用第一個檔案當做MANIFEST.MF檔案,hello.jar作為名稱,將Hello.class和Tom.class打成jar包。其中多了一個引數m,表示要定義MENIFEST檔案
- 執行單元測試
- 生成文件
以上一系列的操作:編譯、執行、單元測試、生成文件、打包部署等,如果手工敲命令進行操作,則會非常繁瑣並且重複
所以有一些IDE如eclipse、intelijIDEA等可以視覺化的操作,但這又帶來了大量的手動操作,引入依賴,編譯,測試,這些都需要手動操作,手動操作意味著低效、容易出錯。
缺點:
1.依賴大量的手工操作,效率低、容易出錯
2.很難在專案中統一所有的IDE配置
所以就出現了我們的構建工具。
最早的構建工具是make,然後有了Ant,然後有maven,gradle
就可以將我們從“編譯,打包,部署,測試”這些程式化的工作上解放出來,我們只需要關注問題本身與解決
Maven對以上“編譯,打包,部署,測試”的步驟梳理為自動化的指令碼:
[1]mvn clean:清理
[2]mvn compile:編譯主程式
[3]mvn test-compile:編譯測試程式
[4]mvn test:執行測試
[5]mvn package:打包
[6]mvn install:安裝
[7]mvn site:生成站點
[8]mvn deploy:部署
(二)依賴管理
比如我們專案依賴A,B,C,而他們底層還依賴其他第三方包
1)我們首先要知道他們之間的依賴關係,如果所有jar包之間的依賴都需要程式設計師自己非常清楚瞭解,那麼極大增加學習成本
2)還需要手動將他們全部都引入,手動“複製”、"貼上"到WEB-INF/lib目錄下
3)下載這些jar包也需要手動下載,去官網或者其他途徑下載
為了解決以上問題,maven將每個三方包做了唯一標識,也就是依賴管理的底層基礎-------座標。Maven座標的元素就包括:groupid、artifactID、version、packaging、classifier
Groupid:定義其隸屬的公司或者專案,它的表示方式是域名反向一一對應,如spark專案:org.apache.spark
Artifactid:定義專案名或者模組名-
Version:專案的版本號
Packaging:定義打包方式,可以打包為jar包、war包等,不定義時預設為jar
上述5個元素中,groupid、artifactid、version是必須定義的,packaging是可選的(預設為jar),而classifier是不能直接定義的
這個值是通過某些特定的外掛生成的,比如我們打包a-1.0-javadoc.jar,a-1.0-sources.jar文件或者原始碼,javadoc和sources就是classifier。
如果一個專案比較龐大,裡面很多模組,那麼groupid這一層就定義到專案名這一級別,artifactid定義到模組名,如spark的專案
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-sql_2.11</artifactId>
<version>2.3.0</version>
</dependency>
ArtifactID定義模組名的時候,推薦的做法是專案名稱作為字首。如果沒有字首,那麼就會看到很多core_2.11-2.3.0.jar,而加了之後spark-core_2.11-2.3.0.jar才能比較好的識別
但如果是一個沒有子模組的專案,則groupid這一層就定義到公司這一級別,artifactid定義到專案級別,如fastjson的專案
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
比如我們自己的專案中:
<groupId>com.mycompany.department</groupId>
<artifactId>project1</artifactId>
<version>1.0-SNAPSHOT</version>
依賴管理
有了maven的座標唯一標識之後,就可以做依賴管理了,就是通過一個核心的配置pom.xml
在pom.xml中我們寫入三個
可以看到它生成的依賴是多於3個了,因為這三個依賴自己底層還依賴其他,maven就幫我們把他們都引入進來了
能夠引入進來的原因就是我們依賴的elasticsearch的pom檔案,它裡面也有它自己的一系列依賴
所以座標唯一標識一個專案
Pom定義專案之間的聯絡,通過配置的方式實現依賴管理