Maven必要的知識點 原

一、簡介

    maven是每個java開發者都離不開的工具。以往每次使用maven都只是使用到了一些基本的、現成的知識,對maven本身缺少系統性的認知,也不知道一些必要的知識點。這幾天查看了相關的一些資料,整理了一下Maven的基礎和必要的知識點。

二、Maven的安裝和配置

    maven其實是一個基於jvm平臺的工具,因此安裝maven前首先保證java的環境變量是可用的。下載maven軟件包解壓縮之後,有如下目錄:

    

    把bin目錄所在的完整目錄配置到PATH環境變量,此時就可以在控制檯使用mvn命令了。嘗試執行mvn -v  如若正常輸出版本後即成功。

    bin目錄下包含了mvn運行的腳本,當中的mvn.bat腳本是windows的腳本,在命令行輸入任何一條mvn命令時,都是在調用這個mvn腳本。conf目錄下包含了一個很重要的文件settings.xml。這個文件定義了maven本地倉庫、遠程倉庫、http代理、私服等等。

三、~/m2

    ~指的是用戶目錄,如C:\Users\liXiao\,這個m2目錄是maven默認的存放setting.xml文件和repository倉庫文件的地址。但是一般的,我們會使用conf目錄下的setting文件,並在這個setting文件裏面配置自己的本地倉庫,如在文件中修改localRepository屬性:

<!--設置自己的maven本地倉庫-->
<localRepository>E:\MyRepository</localRepository>

四、Maven座標

<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.8</version>
<packaging>jar</packaging>

 這樣一個熟悉的pom文件的一組配置,就表示一個maven倉庫中實際存在的durid的jar包。

    像這樣一組配置,叫做maven的座標定義。

五、構建maven項目

目錄結構如下

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如下:

/**
 * 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)的生命週期包括以下階段(注意:這裏是簡化的階段):

  • 驗證(validate) - 驗證項目是否正確,所有必要的信息可用
  • 編譯(compile) - 編譯項目的源代碼
  • 測試(test) - 使用合適的單元測試框架測試編譯的源代碼。這些測試不應該要求代碼被打包或部署
  • 打包(package) - 採用編譯的代碼,並以其可分配格式(如JAR)進行打包。
  • 驗證(verify) - 對集成測試的結果執行任何檢查,以確保滿足質量標準
  • 安裝(install) - 將軟件包安裝到本地存儲庫中,用作本地其他項目的依賴項
  • 部署(deploy) - 在構建環境中完成,將最終的包複製到遠程存儲庫以與其他開發人員和項目共享。

這些生命週期階段(以及此處未顯示的其他生命週期階段)依次執行,以完成默認生命週期。給定上述生命週期階段,這意味着當使用默認生命週期時,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中叫做反應堆

繼承與傳遞依賴的關係和區別

    這是很重要的知識點。

繼承: 

  1.     父項目的<package>屬性必須是pom
  2. 子項目能夠直接引用父項目的依賴,不需要在自己pom中聲明。
  3. 子項目能夠直接使用父項目的properties屬性,不需要在自己pom中聲明。
  4. 子項目能夠引用父項目中聲明的dependencyManagement下的依賴版本,如父項目中有:
<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。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章