Mave基本概念與核心配置
Maven的安裝與核心配置
1、安裝Maven
1)、官網下載 Maven (http://maven.apache.org/download.cgi);
2)、解壓指定目錄;
3)、配置環境變數;
4)、使用mvn -version
檢視Maven是否安裝成功。
2、編譯
1)、建立Maven的一個專案名叫demo-maven; 2)、在demo-maven目錄下建立src資料夾,在src資料夾內建立一個Hello.java檔案,檔案內容如下:
public class Hello { public static void main(String args[]){ System.out.println("Hello World!"); } }
3)、在demo-maven目錄下建立並編寫pom.xml檔案;
<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代表pom.xml檔案的版本,二不是maven的版本--> <modelVersion>4.0.0</modelVersion> <!-- 每一個Maven專案都有一個座標,它的座標由三個點組成: groupId、artifactId和version。 我們Maven的專案名叫什麼artifactId節點內的值就是什麼 --> <groupId>demo</groupId> <artifactId>demo-maven</artifactId> <version>1.0.SNAPSHOT</version> </project>
4)、進入demo-maven目錄使用mvn compile
命令進行編譯;
從這張圖片可以看出時編譯完成併成功了,但是上面顯示No sources to compile,意思是說沒有任何的class檔案被編譯,在demo-maven資料夾和src資料夾內沒有任何的class編譯檔案。但是編譯又是成功的,這又是為什麼呢?其實在我們剛剛的pom.xml檔案裡面並沒有指定java的類檔案路徑,也沒有指定輸出的class檔案的路徑在哪裡。我們是不是需要在pom.xml檔案裡面配置這兩個檔案的路徑呢?其實是不用配置的,在這裡,maven使用了一個在軟體設計上的一個設計思想,叫約定大於配置。在這個裡面maven已經指定好了已src/main/java這個目錄下的檔案就代表著java的類檔案。這麼做的好處在於省去了在pom.xml檔案中指定java類檔案路徑的配置了,規範了我們開發工程的結構。
mvn compile
命令編譯,如下圖所示:
我們重新執行編譯命令後將class檔案編譯到了F:\mavens\demo-maven\target\classes這個目錄,這個編譯目錄同樣的也是採用的約定大於配置的一種軟體設計理念。
3、打包
Maven不止能進行編譯,還能進行打包,我們可以使用mvn package
命令將專案打成一個jar包或者一個war包,如圖:
我們在執行mvn package
的時候並沒有執行mvn compile
編譯命令,為什麼能打包成功呢?因為我們執行打包命令的時候,maven順便將編譯命令也執行完成了。
4、Maven依賴管理
在沒有Maven之前 ,我們都是把jar包放到專案的src/lib資料夾下面。這樣做的缺點就是專案特別大,並且不利於管理jar包,如果jar包有衝突就更加麻煩了。後來Maven就引入了一個jar包的依賴管理,這樣就不需要將jar包放到lib目錄下了,而是把jar包放到了本地倉庫下面,如果本地倉庫沒有這個jar包,Maven就會自動的去遠端倉庫下載,這樣管理依賴包的時候就特別方便。 Maven下載jar包順序如圖: Maven會預設將下載下來的jar放到C盤,並且是去訪問國外的Maven中心去下載jar,所以這就導致C盤可用容量越來越小並且下載jar的速度也很慢。我們可以在maven的settings.xml檔案內配置maven將jar包存放路徑和阿里雲私服。將以下配置內容放到settings.xml檔案內即可:
<localRepository>E:/mvn-resp</localRepository>
<mirror>
<id>alimaven</id>
<mirrorOf>central</mirrorOf>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
</mirror>
二、Maven核心配置
1、專案 依賴(內部、外部)
專案依賴是指maven通過依賴傳播、依賴優先原則、可選依賴、排除依賴、依賴範圍等特性來管理專案的第三方依賴。 1)、依賴傳播特性: 我們的專案中基本上會依賴第三方元件,而第三方元件又會依賴其它元件遇到這種情況Maven會將依賴網路中的所有節點全部載入進專案的classpath,這就是依賴的傳播特性。如果我們的專案依賴了Spring-webmvc,Spring-webmvc依賴了commons-loggin,那麼我們在新增Spring-webmvc依賴後也會將commons-logging的依賴也新增進來。 2)、最短路徑優先原則: 基於依賴傳播特性,導致整個依賴網路會很複雜,難免會出現相同元件不同版本的情況。Maven此時會基於依賴優先原則選擇其中一個版本。 第一原則:最短路徑優先原則,在下面這個Spring-webmvc這個依賴通過依賴網路圖可以看到Spring-webmvc是依賴了commons-logging的,如圖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.0.4.RELEASE</version>
</dependency>
我們在pom.xml內再直接加入1.2版本的commons-logging的依賴,maven最終是通過最短路徑優先原則直接引入1.2版本的commons-logging的依賴,因為專案是直接依賴的1.2版本的,1.3版本的commons-logging是通過SpringMVC的jar去依賴的。
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
3)、相同路徑下配置在前的優先;
我們建立一個Maven的工程來演示一下這個原則,新建的一個Maven父工程demo-parent,在這個父工程內新建兩個子工程demo-server和demo-client,其中demo-server工程依賴了demo-client和spring-webmvc4.0.4,spring-webmvc又依賴了springweb4.0.8,demo-client依賴了springweb4.3.8,那麼最終maven會引入springweb哪個版本的依賴呢?工程圖如下:
在這個情況下maven引入的是spring-web4.3.8版本的依賴,因為demo-client配置在spring-webmvc的前面,所以引入的是4.3.8版本的spring-web:
3)、可選依賴:
可選依賴表示這個依賴不是必須的。通過在 <dependency>
新增<optional>true</optional>
表示,預設是不可選的。可選依賴不會被傳遞。
4)、排除依賴:
排除指定的間接依賴。通過配置 <exclusions>
配置排除指定元件,舉例如下:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.0.4.RELEASE</version>
<!--排除當前對springweb的依賴-->
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</exclusion>
</exclusions>
</dependency>
5)、依賴範圍:
像junit這種元件,我們只有在執行測試用例的時候要去用到,這就沒有必要在打包的時候把junit.jar構建到專案中了,我們可以通過Maven的依賴範圍配置<scope>
來達到這種目的。Maven一共支援幾種依賴範圍:
compile(預設): 編譯範圍,編譯和打包都會依賴。
**provided:**提供範圍,編譯時依賴,但不會打包進去。
**runtime:**執行時範圍,打包時依賴,編譯不會。
**test:**測試範圍,編譯執行測試用例依賴,不會打包進去。
**system:**表示由系統中CLASSPATH指定。編譯時依賴,不會打包進去。配合<systemPath>
一起使用。system除了可以引用系統classpath中的包,也可以用於引入系統非maven收錄的第三方jar,做法是將第三方jar放到專案的lib目錄下,然後配置相對應的路徑,但是因為system不會打包進去所以需要配合maven-dependency-plugin
外掛一起使用。當然推薦大家通過將第三方jar手動install到倉庫。
<!-- system 的通常使用方式-->
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>${java.version}</version>
<scope>system</scope>
<optional>true</optional>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
<!-- system 另外使用方式 ,將工程內的jar直接引入 -->
<dependency>
<groupId>jsr</groupId>
<artifactId>jsr</artifactId>
<version>3.5</version>
<scope>system</scope>
<optional>true</optional>
<systemPath>${basedir}/lib/jsr305.jar</systemPath>
</dependency>
<!-- 通過外掛 將system 的jar 打包進去。 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>compile</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/lib</outputDirectory>
<includeScope>system</includeScope>
<excludeGroupIds>com.sun</excludeGroupIds>
</configuration>
</execution>
</executions>
</plugin>
將第三方jar手動加入倉庫命令:mvn install:install-file -Dfile=abc_client_v1.20.jar -DgroupId=tuling -DartifactId=tuling-client -Dversion=1.20 -Dpackaging=jar
2、專案聚合與繼承
1)、聚合
是指將多個模組整合在一起,統一構建,避免一個一個的構建。聚合需要一個父工程,然後使用<moduls>
進行配置其中對應的是子工程的相對路徑,專案聚合的優點在於指需要對父專案進行打包,不需要對子模組一個一個的打包了,這就節省了我們的開發時間,moduls
配置如下:
<modules>
<module>demo-server</module>
<module>demo-client</module>
</modules>
2)、專案繼承
繼承是指子工程直接繼承父工程 當中的屬性、依賴、外掛等配置,避免重複配置,並且這三個配置子工程都可以進行重寫,重寫之後以子工程的為準。專案繼承使用<parent>
配置,如下:
<parent>
<groupId>demo-parent</groupId>
<artifactId>demo-parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
3)、依賴管理 通過繼承的特性,子工程是可以間接依賴父工程的依賴,但多個子工程依賴有時並不一至,這時就可以在父工程中加入 宣告該功程需要的JAR包,然後在子工程中引入,如下所示:
<!-- 父工程中宣告 junit 4.12 -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</dependencyManagement>
<!-- 子工程中引入 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
3、專案構建配置
基本配置示例:
<defaultGoal>package</defaultGoal>
<directory>${basedir}/target2</directory>
<finalName>${artifactId}-${version}</finalName>
基本配置示例說明:
defaultGoal:執行構建時預設的goal或phase,如jar:jar或者package等
directory:構建的結果所在的路徑,預設為${basedir}/target目錄
finalName:構建的最終結果的名字,該名字可能在其他plugin中被改變
在pon.mxl檔案的<build>
節點下可以配置<resources>
,這個<resources>
是配置的一個打包的一個源,在預設情況下是在src/main/java目錄下只會打包.java檔案,但是有的時候我們會把MyBatis的一些orm的配置檔案也寫到我們的dao層裡面,這個時候使用預設的方式打包肯定是把那個orm的配置檔案打不進去的。配置如下:
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.MF</include>
<include>**/*.XML</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*</include>
<include>*</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
說明:
resources:build過程中涉及的資原始檔。
targetPath:資原始檔的目標路徑。
directory:資原始檔的路徑,預設位於${basedir}/src/main/resources/
目錄下。
includes:一組檔名的匹配模式,被匹配的資原始檔將被構建過程處理。
excludes:一組檔名的匹配模式,被匹配的資原始檔將被構建過程忽略。同時被includes和excludes匹配的資原始檔,將被忽略。
filtering: 預設false ,true 表示 通過引數對資原始檔中 的${key}
在編譯時進行動態變更。