Maven從入門到放棄
- 2019 年 10 月 3 日
- 筆記
1.maven是什麼?
maven是Apache下的一個純java開發的一個開源項目,它是一款能夠抽象構建過程,並且提供依賴管理,中央倉庫,自動下載構建等功能的項目構建工具。
2.為什麼要使用maven工具構建項目?
假如我們在開發兩個Java項目,暫時稱之為A,B,這兩個項目中對於一些特殊功能會有互相依賴的情況下,該如何做兩者之間較好的關聯呢?是打算在A,B兩邊共用一套程式碼進行關聯嗎?( 這樣的做法會非常難以進行後期的維護 )
如果我們將共用的程式碼打包成jar引入項目中使用的話,那麼後期進行程式碼更新的話是否又要對所有引入的jar進行更新呢?這樣的做法似乎非常繁瑣。
回想起以前做開發的時候,由於maven技術還沒有出現,使用ssh框架進行開發的時候,所有的jar都需要人為的進行統一導入和維護,導致後期的維護難度極高。
而maven正是可以解決以上所說的這些問題。
3.maven會如何進行jar的管理呢?
在maven這款工具裡面,有一個特別的概念叫做坐標。這個坐標可不是我們數學裡面說的那個坐標,但是在設定上確實和數學的坐標有一點類似,就是每個坐標都會擁有屬於它自己的唯一標識。在maven裡面也不例外:
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency>
例如上邊的這段坐標資訊,groupId 通常會用於標識該jar所屬的實際項目,由於通常一個項目可能會劃分為了多個模組,因此artifactId 則是對於該項目的某個模組進行了一個明確的標識。version元素更多的是定義了該構件的真實版本。通常我們會稱呼這一段 dependency 為依賴。
對於依賴的讀取還有一個叫做scope的配置
scope的分類 | 講解 |
---|---|
compile |
默認情況下就是compile類型, 意味著該依賴既要參與編譯又要參與後期的測試等環節 |
test | 表示該依賴僅僅參加和測試有關的工作 |
provided |
可以參與編譯,測試,運行等周期, 但是在打包的時候會進行exclude的相應操作, 其他方面和compile差異不大 |
runntime | 在編譯環節不會參與進來,個人感覺和compile差異不大 |
system |
通常是指不從倉庫讀取依賴,而是通過本地路徑來讀取依賴, 因此常與systemPath標籤結合使用 |
當然如果對於每個依賴我們都進行相應單獨的version設置,那麼管理起來會有些繁瑣,因此可以使用或者標籤進行統一的管理,例如下方的這兩組案例:
基於parent的依賴管理:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.4.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent>
基於properties的依賴管理,在properties裡面我們可以進行整個項目的統一字符集編碼管理或者對於一些依賴jar包統一版本號的管理:
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <lombok.version>1.16.6</lombok.version> <aspectj.version>1.8.11</aspectj.version> <common.version>3.4</common.version> <codec.version>1.10</codec.version> <swagger2.version>2.7.0</swagger2.version> <mybatis.version>3.3.0</mybatis.version> <mybatis-spring-boot.version>1.3.1</mybatis-spring-boot.version> <pagehelper.version>1.2.3</pagehelper.version> <springfox-swagger-ui.version>2.7.0</springfox-swagger-ui.version> <mysql.version>5.1.6</mysql.version> <mongodb.version>3.2.2</mongodb.version> </properties>
4.maven的倉庫
那麼當我們將相應的依賴導入到了工程裡面之後,又會發生什麼事情了呢?
maven的內部會有一個從網上邊下載依賴的功能,我們通常稱這個擁有依賴jar的平台為倉庫。
在maven裡面倉庫有分為多種:本地倉庫,第三方倉庫,中央倉庫
通常被下載下來的jar會存在開發者電腦上的本地倉庫,這個默認的地址是在 $user.home/.m2/repository目錄底下:
這裡面存儲了許多自己曾經下載過的jar,這樣就可以避免日後再次使用到相同jar時二次請求中央倉庫了。
中央倉庫是指maven官方自己維護的一個遠程公用倉庫:
http://repo1.maven.org/maven2 在這裡面提供了豐富的jar包供開發人員進行下載使用。有時候我們在開發中會遇見下載jar包網速過慢的情況,這個時候可以嘗試將mirrors配置修改為訪問阿里雲鏡像的配置:
<mirror> <id>alimaven</id> <name>aliyun maven</name> <url>http://maven.aliyun.com/nexus/content/groups/public/</url> <mirrorOf>central</mirrorOf> </mirror>
第三方倉庫通常是指公司自己內部搭建的公共類庫站點,只提供給公司內部共享服務所使用,通常都是搭建在區域網內部使用,而且對於內部私服的連接,通常公司都會有相關的帳號密碼進行控制。
Nexus就是一款較為強大的Maven倉庫管理工具,它極大地簡化了自己內部倉庫的維護和外部倉庫的訪問。利用Nexus你可以只在一個地方就能夠完全控制訪問 和部署在你所維護倉庫中的每個Artifact。
Nexus是一套“開箱即用”的系統不需要資料庫,它使用文件系統加Lucene來組織數據。Nexus 使用ExtJS來開發介面,利用Restlet來提供完整的REST APIs,通過m2eclipse與Eclipse集成使用。Nexus支援WebDAV與LDAP安全身份認證。
除了Nexus以外,還有挺多知名的倉庫管理工具,例如說JFrog Artifactory
5.maven工程的項目結構是如何的呢?
在idea編譯器裡面,對於maven工程的創建時候,默認的結構通常都是如下所示:
在開發的時候,通常程式碼編寫都是在main文件夾底下進行,而如果需要編寫相應的測試程式碼則在test目錄底下進行,java目錄下一般是放置我們的程式碼內容,resources目錄底下更多的是存放一些我們的配置文件,例如說xml,yml,properties這類型的文件內容。
當然如果是創建maven-web結構的工程的話,可以在建立maven工程的時候選擇相應的構建模板:
項目結構如下所示:(可能idea版本不同,最終的成效截圖會有所出入)
當然,現在的項目大多都是基於父子工程的偏多,maven裡面也支援這種工程的搭建,通常我們可以事先構建好一個父工程結構,然後再在父工程的基礎上邊構建相應的module工程。例如下邊的工程截圖:
6.maven的常用命令和生命周期
其實maven它本身是具有三套獨立的生命周期的,這三套的生命周期分別是clean,default,site,分別有著不同的職責:清理,構建,建立站點
maven的三套生命周期之間實質上是需要互相依賴的,通常都是後者依賴於前者的關係,以clean生命周期為例,它包含的階段有pre-clean、clean和post-clean。
當用戶調用pre-clean的時候,只有pre-clean階段得以執行;當用戶調用clean的時候,pre-clean和clean階段會得以順序執行;當用戶調用post-clean的時候,pre-clean、clean和post-clean會得以順序執行。
maven之所以將整個項目的階段劃分得如此細緻,我個人的觀點是這種細粒度的劃分更加地利於工程構建過程中的排查錯誤,不同的環節由不同的插件來負責這一模組,當拋出了異常報錯,我們就只需要對該環節進行分析,例如編譯出錯,打包出錯等。
maven自身提供了非常多的命令供我們使用,下邊列舉了我們常用的命令基本如下:
-
mvn archetype:create :創建 Maven 項目
-
mvn compile :編譯源程式碼
-
mvn test-compile :編譯測試程式碼
-
mvn test : 運行應用程式中的單元測試
-
mvn site : 生成項目相關資訊的網站
-
mvn clean :清除目標目錄中的生成結果
-
mvn package : 依據項目生成 jar 文件
-
mvn install :在本地 Repository 中安裝 jar
7.通過profile文件來指定特定的編譯環境
在實際的項目開發過程中,我們通常會需要結合實際的應用場合切換不同的運行環境(dev,test,pre,pro),在不同的環境中我們通常需要讀取不同的配置文件,例如不同的數據源配置,埠號配置等。
如果每次切換環境的時候都要開發人員進行相關的手動修改配置的方式來進行的話,那麼實際的工作效率會顯得較低,不妨可以試試使用pom裡面提供的profile配置:
<profiles> <profile> <!-- 本地開發環境 --> <id>dev</id> <properties> <profiles.active>dev</profiles.active> </properties> <activation> <activeByDefault>true</activeByDefault> </activation> </profile> <profile> <!-- 測試環境 --> <id>test</id> <properties> <profiles.active>test</profiles.active> </properties> </profile> <profile> <!-- 生產環境 --> <id>pro</id> <properties> <profiles.active>pro</profiles.active> </properties> </profile> </profiles>
在pom文件裡面配置以上相應的profile內容之後,在進行工程打包的時候默認通過mvn clean package -Pdev(對應profile文件的id)的方式來判斷不同環境下的讀取方式。
這樣我們就可以更加專心的進行程式碼開發工作,基於這種思路,我們可以通過編寫相應的腳本來實現不同環境下自動化打包的功能。