maven是每一個java開發者都離不開的工具。以往每次使用maven都只是使用到了一些基本的、現成的知識,對maven自己缺乏系統性的認知,也不知道一些必要的知識點。這幾天查看了相關的一些資料,整理了一下Maven的基礎和必要的知識點。java
maven實際上是一個基於jvm平臺的工具,所以安裝maven前首先保證java的環境變量是可用的。下載maven軟件包解壓縮以後,有以下目錄:web
把bin目錄所在的完整目錄配置到PATH環境變量,此時就能夠在控制檯使用mvn命令了。嘗試執行mvn -v 如若正常輸出版本後即成功。spring
bin目錄下包含了mvn運行的腳本,當中的mvn.bat腳本是windows的腳本,在命令行輸入任何一條mvn命令時,都是在調用這個mvn腳本。conf目錄下包含了一個很重要的文件settings.xml。這個文件定義了maven本地倉庫、遠程倉庫、http代理、私服等等。apache
~指的是用戶目錄,如C:\Users\liXiao\,這個m2目錄是maven默認的存放setting.xml文件和repository倉庫文件的地址。可是通常的,咱們會使用conf目錄下的setting文件,並在這個setting文件裏面配置本身的本地倉庫,如在文件中修改localRepository屬性:windows
<!--設置本身的maven本地倉庫--> <localRepository>E:\MyRepository</localRepository>
<groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.8</version> <packaging>jar</packaging>
這樣一個熟悉的pom文件的一組配置,就表示一個maven倉庫中實際存在的durid的jar包。api
像這樣一組配置,叫作maven的座標定義。tomcat
目錄結構以下服務器
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> <groupId>com.yue</groupId> <artifactId>study-maven</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.7</version> <scope>compile</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.7.0</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>1.2.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.yue.Hello</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
hello.java以下:jvm
/** * Created by 千里明月 on 2018/10/30. */ public class Hello { public static void main(String[] args) { // Hello hello = new Hello(); hello.sayhello(); } public void sayhello(){ System.out.println("hello world"); } }
1.依賴配置:
<depndencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies>
2.依賴範圍:
test:指的是測試範圍有效,在編譯打包、運行時都不會使用這個依賴。本maven項目中,使用了junit依賴,可是範圍是test,所以只能在測試目錄src/test/java下的java文件中使用,hello.java不能使用。
compile:指的是編譯範圍有效,在編譯、測試、打包、運行時都會將依賴存儲進去。若是沒有指定,就會默認使用該依賴範圍。例如:hibernate jar包。
provided:在編譯和測試的過程有效,最後生成包時不會加入,運行時天然也沒效果。例如:servlet-api,由於servlet-api,tomcat等web服務器已經存在該jar包了,若是再打包可能會有衝突。
runtime:在測試、運行的時候依賴,在編譯的時候不依賴。例如:JDBC驅動,項目代碼只須要jdk提供的jdbc接口,只有在執行測試和運行項目的時候才須要實現jdbc的功能。
system:系統依賴範圍。該依賴範圍與provided所表示的依賴範圍一致,對於編譯和測試有效,但在運行時無效。只是使用system範圍依賴時必須經過systemPath元素顯式地指定依賴文件的路徑。
import(Maven 2.0.9及以上):導入依賴範圍。
3.傳遞性依賴:
Maven的依賴是具備傳遞性的,好比A->B,B->C,那麼A間接的依賴於C,這就是依賴的傳遞性,其中A對於B是第一直接依賴,B對於C是第二直接依賴,C爲A的傳遞性依賴。
4.依賴排除:
傳遞性依賴會給項目隱式的引入不少依賴,這極大的簡化了項目依賴的管理,可是有些時候這種特性也會帶來問題,它可能會把咱們不須要的jar包也引入到了工程當中,使項目結構變得更復雜。或者你想替換掉默認的依賴換成本身想要的jar包,這時候就須要用到依賴排除。
如:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>3.2.8</version> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency>
5.可選依賴:
當項目A依賴項目B時,B中的某個依賴不想被A使用,那麼也能夠經過配置<optional>true</optional>完成
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.7</version> <scope>compile</scope> <optional>true</optional> </dependency>
maven有三個內置的生命週期:默認(default),清潔(clean)和站點(site)。在默認(default)的生命週期處理你的項目部署,將清潔(clean)的生命週期處理項目的清理,而網站(site)的生命週期處理你的項目站點文檔的建立。
這些構建生命週期中的每個由構建階段的不一樣列表定義,其中構建階段表示生命週期中的階段。
例如,默認(default)的生命週期包括如下階段(注意:這裏是簡化的階段):
這些生命週期階段(以及此處未顯示的其餘生命週期階段)依次執行,以完成默認生命週期。給定上述生命週期階段,這意味着當使用默認生命週期時,Maven將首先驗證項目,而後嘗試編譯源代碼,運行這些源代碼,打包二進制文件(例如jar),運行集成測試軟件包,驗證集成測試,將驗證的軟件包安裝到本地存儲庫,而後將安裝的軟件包部署到遠程存儲庫。
換句話說,在生命週期裏面階段是連續的,在不出錯的前提下,好比執行打包(package)時就必定是執行了測試(test)以後再執行。
當項目A中聚合了項目B和項目C時,聚合配置代碼:
<groupId>com.yue</groupId> <artifactId>A</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>B</module> <module>C</module> </modules>
其中module的路徑爲相對路徑。
當編譯項目A時,會先進行A的編譯,再編譯B,再編譯C。
繼承配置代碼:
<parent> <artifactId>study-maven</artifactId> <groupId>com.yue</groupId> <version>1.0-SNAPSHOT</version> </parent> <artifactId>study-maven-child</artifactId>
繼承爲了消除重複,咱們把不少相同的配置提取出來,例如:grouptId,version等.
當項目A繼承項目B時,A能夠直接引用B的依賴而不須要配置dependency。
當編譯子項目時,會先進行父項目的編譯。
像這樣一種肯定各個模塊的編譯順序的機制,在maven中叫作反應堆。
這是很重要的知識點。
繼承:
<dependencyManagement> <dependencies> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.5</version> </dependency> </dependencies> </dependencyManagement>
可在子項目中忽略版本號引用:
<dependencies> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> </dependency> </dependencies>
傳遞依賴:
情景:項目A依賴於項目B,項目B依賴於項目C。
1. 項目A中的配置:
<dependencies> <dependency> <groupId>com.yue</groupId> <artifactId>B</artifactId> <version>1.0</version> </dependency> </dependencies>
如此,項目A能夠直接使用項目B的依賴,不須要其餘配置。
2. 項目C和B的<package>屬性必須是jar
3. 項目A不能使用項目B和C項目的properties屬性
4. 項目A不能享用B、C項目中聲明的dependencyManagement。