1. 程式人生 > >Maven基本概念與核心配置

Maven基本概念與核心配置

Maven的安裝與核心配置

1、安裝Maven

  1)、官網下載 Maven (http://maven.apache.org/download.cgi);
  2)、解壓指定目錄;
  3)、配置環境變數;
配置環境變數
配置path
  4)、使用mvn -version檢視Maven是否安裝成功。
驗證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命令進行編譯;
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類檔案路徑的配置了,規範了我們開發工程的結構。
  現在我們在demo-maven的目錄下建立好src/main/java這個目錄,再將Hello.java檔案移動到src/main/java這個路徑下,然後再demo-maven目錄下使用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} 在編譯時進行動態變更。