對於開發者來說,Maven最強大的功能莫過於 dependency management了!
在之前文章 Maven-05-一個簡單的POM範例 我們看到POM裡定義了一組 junit 的dependency,所以在執行 mvn install 時,Maven 會先檢查本機的 repository 是否有 junit 相關的 artifact ,如果沒有就會從網路上下載,然後放到 ~/.m2/repository/junit/junit/3.8.1/junit-3.8.1.jar
這邊我們可以觀察到 Maven 自動下載的東西除了jar 檔,還包括了其他檔案像是包了原始碼的jar,還有一個很關鍵的 junit-3.8.1.pom,為什麼 Maven 還會下載 junit的POM呢?
大家可以試著想想,如果今天我們需要的不是junit 這麼單純的套件,我們需要在專案裡使用 Hibernate,從它的 POM 我們得知 Hibernate 本身也有許多 dependencies,難道我們必須在自己專案的 POM 把這些 Hibernate 的 dependency 也全部都寫出來嗎??
答案當然是:NO !!
我們只需要定義 Hibernate dependency,Maven 就會自動把它關聯的 dependency 也一併下載回來,這種機制稱為 “transitive dependencies”, 實際上的運作方式是 Maven 會去查看 dependency 的 POM,並確認是否有相關的 dependency
在junit 的 <dependency> 定義裡,有一個 <scope>test</scope>,這是另一個重要的概念 ,常用的 dependency scope 有下列幾種:
- compile: 如果沒有定義<scope>, 預設值就是 compile,顧名思義指的是在編譯專案程式碼時需要這個 dependency
- test: 指的是在這兩個 goal compiler:testCompile (編譯測試程式碼), surefire:test (執行unit test) 才會引用的dependency,正式產出的 jar (或其它格式) 並不會包含 scope 為 test 的 dependency
- provided: 通當在 web 專案比較常看到這種 scope,指的是在編譯時有需要,但在正式產出war時並不會包含在一起,像是 jsp, servlet 這種 dependency,我們會在開發時用到相關的api,但實際提供這些 dependency 的是運行 web app 的 ap server
更多 dependency scope 可參考
https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope