Maven的基礎瞭解與使用

首發日期:2018-11-04java


Maven的介紹:

什麼是Maven:

  • Maven是apache旗下的一個java開源項目。
  • Maven是一個項目管理工具,它能夠幫助咱們管理項目
  • 可使用Maven對java項目進行項目構建(構建包括清理、編譯、測試、報告、打包、部署六個過程,你能夠認爲是一個項目的從代碼到完整可運行項目的過程)、依賴管理。

爲何要學習maven?

以一個例子說一下maven的好處,說了它的好處,web

1.maven能夠幫咱們管理依賴。在以往的時候,咱們都是手動的導入jar包,而後build path;在導入jar包以前,咱們須要去查找有哪些包,須要哪些包,這是一個很是繁雜的問題,若是你不是「老司機」的話,你可能會遺漏某些jar包;而在maven中,咱們可使用pom.xml來聲明須要哪些依賴包,而後maven就會根據pom.xml中的信息去獲取倉庫中的依賴包的引用,這就至關於導入了jar包。並且,maven存儲了大量的jar包和大量的依賴規則,因此你能夠直接去百度搜索一下某個關鍵字+maven,就能夠查找到某個框架或工具的依賴信息,直接把這個依賴信息拷貝到pom.xml中,maven就會幫你管理這個依賴。spring

2.maven能夠幫咱們進行工程管理。在以往的時候,咱們開發一個項目都是在一個工程中開發,但事實上這對多人開發並不友好,多個開發者之間的開發產生了耦合關係,這對整合形成了一些小困擾(但並非說很差,只是說有更好的手段)。而使用maven以後,能夠創建多個工程來組成一個項目,在不一樣的工程中開發不一樣的模塊,而多個工程之間的關係由maven管理,maven能夠幫咱們把多個工程組合成一個項目。數據庫



安裝與配置:


下載:

點擊連接,下載Maven:
apache

下載完了以後,直接解壓便可,它是免安裝的。windows


配置環境變量

  • 配置JAVA_HOME環境變量,值是jdk程序根目錄【若是已經配置過的,能夠省略】
  • %JAVA_HOME%\bin添加到path環境變量中【若是已經配置過的,能夠省略】【注意不要弄亂了path的值】
  • 配置MAVEN_HOME環境變量,值是maven程序根目錄
  • %MAVEN_HOME%\bin添加到path環境變量中【注意不要弄亂了path的值】

測試安裝結果:

配置了環境變量後,能夠在CMD中鍵入mvn -v來測試是否能夠運行,下面是個人輸出結果:api

Apache Maven 3.5.4 (1edded0938998edf8bf061f1ceb3cfdeccf443fe; 2018-06-18T02:33:14+08:00)
Maven home: J:\software\apache-maven-3.5.4\bin\..
Java version: 1.8.0_91, vendor: Oracle Corporation, runtime: E:\SOFTWARD\Java\jdk1.8.0_91\jre
Default locale: zh_CN, platform encoding: GBK
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"

Maven概念:

在學會maven以前,先了解幾個概念。下面的概念瞭解便可,後面會在實際的配置中涉及。tomcat

座標

在以往的build path過程當中,其實只是把jar包的路徑引用添加到eclipse中,eclipse知道須要的包的路徑以後,在編譯的時候會去引用。服務器

而maven能夠根據座標來指定使用哪一個依賴包,座標通過必定的組合規則就能夠得出依賴包所在的路徑,maven會根據座標對應的路徑在倉庫中來查找jar包。

  • maven用三個向量來組成一個座標,這個座標肯定惟一的依賴包:

    • groupid:公司或組織域名倒序+項目名
    • artifactid:模塊名\工程名
    • version:jar包版本
  • maven會根據座標在倉庫中來查找jar包,把三個向量拼接起來就是依賴包的路徑。

    • <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-core</artifactId>
              <version>4.3.0.RELEASE</version>
          </dependency>
      <!--對應的路徑轉換格式:groupid/artifactid/artifactid+version+.jar -->
      <!--org/springframework/spring-core/spring-core4.3.0.RELEASE  .jar-->


倉庫

在上面提到了座標,你應該認識到了座標標識了依賴包的路徑,而這個路徑是相對於倉庫的路徑的。爲何須要一個倉庫呢?上面說了eclipse實質上也是經過路徑來導入依賴包的,若是你沒有一個統一的文件夾來管理依賴包的話,零散的依賴包足以讓你頭疼了。而maven的倉庫是一個包含了衆多依賴包的倉庫,並且maven的依賴管理能夠很方便地添加依賴包信息。

  • 倉庫的分類
    • 本地倉庫:本機上的倉庫,一般都會有一個本機倉庫,否則你總是須要從遠程倉庫獲取的話就很費時間了;而事實上maven會指定一個默認的本地倉庫路徑,第一次使用maven的時候,會把maven須要的插件和遠程庫中存儲的jar包下載下來並存儲到本地倉庫中。
    • 遠程倉庫:事實上你能夠給本地倉庫存儲你本身的jar包,而某個jar包本地沒有的時候,就須要從遠程倉庫下載下來。
      • 私服倉庫:是一個遠程倉庫,但距離比較近,一般是企業中本身內部的maven倉庫,一般私服maven倉庫都會使用nexus來搭建。
      • 中央倉庫:是maven維護的遠程倉庫,它裏面存儲的東西比較全。
  • 依賴包的查找順序:先從本地倉庫查找,本地倉庫沒有就去遠程倉庫查找(企業中通常是本地倉庫->私服倉庫->中央倉庫)。當查找到了以後,都會下載到本地倉庫。【記住初始狀況下,maven的倉庫是比較乾淨的,僅僅包含一些基本插件。】
  • 倉庫中存儲的內容:
    • 插件【maven的功能依賴於插件,沒有插件就沒有功能,比如電腦須要驅動,maven的構建是經過插件來實現的】
    • jar包
    • 本身開發的maven工程【其實你應該知道本身是能夠把本身的工程打成jar包,而後能夠在別的工程中導入這個jar包來使用這個jar包中的類,因此你是能夠把本身的類庫放到倉庫中的



入門示例

下面以建立一個maven項目,並使用maven的依賴管理來給項目添加依賴爲例:

建立maven工程:

關於如何建立一個maven項目,下面以eclipse中的爲例,若是你須要idea的,能夠點擊下面的連接學習。
圖解在IntelliJ IDEA中建立第一個Maven項目

新建工程->選擇maven project

添加依賴

在pom.xml中添加下列代碼:

<dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

能夠看得出來,依賴已經導入了咱們項目的類庫。

因此咱們利用依賴包中的類來編寫代碼的時候就不會報錯了。


Maven標準目錄結構

maven要依據必定的目錄規範來管理項目,因此要想用maven管理項目,要遵循規範。下面會講一下目錄定義規範,這樣是面向全手動建立maven項目的時候,在不少時候,都會使用工具來建立,好比eclipse中就能夠直接建立一個maven工程,這個工程遵循maven工程的目錄規範。

約定的目錄結構

maven構建一個工程要遵循這個目錄規範。

  • 工程目錄【下面的縮進程度表明目錄級數】
    • src目錄:存放工程源碼的地方
      • main目錄:存放主程序的源代碼,這裏放的是主體程序代碼。
        • java目錄:存放java源文件
        • resource目錄:存放框架或其餘工具的配置文件
        • 【爲web項目時會多出一個webapp目錄】webapp目錄:存放頁面素材
      • test目錄:存放測試程序的源代碼的地方,這裏放的都是一些測試用的代碼。
        • java目錄:存放java源文件
        • resource目錄:存放框架或其餘工具的配置文件
    • pom.xml文件:這個文件定義了這個maven工程的相關配置。

補充:

  • maven使用一個pom.xml文件來管理依賴。pom中配置依賴信息和maven的一些配置信息,這會在下面講解。

pom配置:

  • pom是Project Object Model項目對象模型的意思。
  • pom.xml是maven工程的核心文件,與構建工程相關的一切配置(依賴信息、插件信息等等)都在這個文件中配置
  • pom.xml中的可配置標籤不少,咱們這裏僅僅介紹常用的。這些常用的也足夠你平常使用了。

常見標籤

  • modelVersion:是pom的版本,通常都是默認生成的,不須要關心
  • groupId:標識當前工程的所屬組織,寫法相似包名。【爲何工程也有這個呢?由於咱們的工程也是能打包到本地倉庫的。】
  • artifactId:當前工程的工程名
  • version標籤:當前工程的版本號
  • dependencies標籤:用於管理這個工程的依賴
    • dependency標籤:指定某個依賴的信息
      • groupId:標識依賴包的所屬組織,寫法相似包名。
      • artifactId:依賴包的包名。
      • version:依賴包的版本。
      • scope標籤:依賴包的依賴範圍。

依賴級別\依賴範圍

依賴信息中的scope標籤是用來定義依賴範圍的。依賴範圍影響依賴的生存週期(就比如遊戲中的特殊狀態,可能一些狀態可用於pk,一些狀態可用於打副本,一些狀態可用於任務,不一樣的地方影響效果是否生效。),依賴範圍的值有如下幾個:

  • compile:編譯級別的依賴會用在編譯、測試、運行的過程當中。默認依賴範圍:compile
  • test:test僅僅針對test目錄下的源文件,因爲test目錄下存放的是test文件,測試文件通常都不會編譯到主程序中,因此test級別的依賴是不會在編譯和運行中生效的。只在測試編譯和測試運行階段可用。這個級別的依賴包例若有junit包,junit僅僅用來測試,在主程序編譯和運行中是不須要它的。
  • provided:provided表明已提供的意思,provided範圍會用來編譯和測試,不會出如今運行中,provided主要用來處理容器也提供了咱們所須要的包的狀況。例如servlet-api這種依賴包tomcat容器也會提供給部署的程序,若是提供多個同名的依賴包可能會致使主程序運行出錯。
  • runtime:在編譯的時候不須要(沒有用到具體類),可是在運行和測試的時候須要用到,就可使用這個。例如數據庫驅動包,它僅僅在運行和測試的時候會使用到這個依賴包。
  • system:相似provided,對於編譯和測試有效,運行時不須要,不建議使用,因此不講

依賴傳遞的導入

要注意,在一個工程中,若是導入的依賴須要一系列依賴(A包須要B包才能正常,那麼也會導入B包),那麼也會導入這一些依賴,例如struts2-core依賴一系列的包。

演示:基於eclipse

僅僅導入struts2-core的時候,maven會自動導入struts2-core所依賴的包:

發現maven自動導入了struts2-core依賴的包(這些依賴包是由struts2-core項目中的pom.xml指定的)

依賴傳遞問題

  • 依賴傳遞的過程當中:
    • 路徑最短者優先
      • A依賴B,B依賴C,C依賴D(版本1.1)
      • A依賴E,E依賴D(版本1.2)
      • 導入時選擇版本D(版本1.2)
    • 路徑相同,先聲明者優先【意思是若是A同時依賴於B和C,而B和C都含有同一個依賴包P,若是在A的繼承聲明中先聲明B,那麼A會繼承B的依賴包P,因此P版本取決於B】

依賴排除

可能會遇到一種狀況,在同一個工程中,A包依賴B包的1.0版本,C包依賴B包的1.5版本。那麼B的1.0和1.5都被引入了。這可能會致使紊亂,由於構建的時候會不清楚使用哪一個版本的B依賴包。這時候咱們須要使用依賴排除來解決這個問題。【通常都是排除低版本】

例如struts2-core依賴javassist包,hibernate-core也依賴javassist包,根據依賴的依賴的導入規則,這時候會有兩個javassist

爲了不紊亂,咱們要使用exclusions排除。在eclipse中,咱們能夠在Dependency Hierarchy中右鍵選中包進行排除,也可使用如下xml式排除:

<dependency>
        <groupId>org.apache.struts</groupId>
        <artifactId>struts2-core</artifactId>
        <version>2.3.34</version>
        <exclusions>
            <!-- 排除struts2-core的依賴中的javassist依賴 -->
            <exclusion>
                <groupId>javassist</groupId>
                <artifactId>javassist</artifactId>
            </exclusion>
        </exclusions>
    </dependency>


依賴的繼承

在創建多個有繼承關係的工程時,父工程的依賴信息會傳遞給子工程。
在父工程中聲明瞭依賴後,就算子工程沒有聲明,也會傳遞到子工程中

版本鎖定

在分模塊開發時,多個子模塊可能會使用上同一個依賴包,那麼如何限定多個子模塊都使用同一版本的依賴包呢?可使用版本鎖定。

  • 在父工程使用dependencyManagement來管理依賴(dependencyManagement不會導入依賴),那麼依賴的版本會被父工程鎖定。
  • 一般狀況下,父工程的依賴會傳遞給子工程(若是你另外也使用了dependencies標籤來聲明依賴),那麼子工程不聲明的時候是沒問題的;若是子工程顯式導入被鎖定版本的依賴時,會報錯,會提示版本被父工程鎖定。
<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.9</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

統一管理依賴版本:

你應該常常見到某個框架的依賴包都是同一版本的,若是咱們將這些依賴信息都添加到pom.xml中,可能會出現多個重複的version標籤,若是你要修改的話是很麻煩的,要逐個逐個去修改版本。

事實上,是能夠統一管理依賴版本的,同一管理依賴版本以後,若是咱們要修改這個框架下的包的版本,那麼只須要修改一處就好了。

  • 使用properties內使用自定義標籤統一版本號,自定義標籤至關於一個變量,後面的version那裏能夠引用這個變量。
<properties>
     <!-- 使用自定義標籤統一版本號,標籤名是自定義的 -->
    <struts2-version>2.3.34</struts2-version>
  </properties>
  
  <dependencies>
    <dependency>
        <groupId>org.apache.struts</groupId>
        <artifactId>struts2-core</artifactId>
        <!--在version標籤中引用 -->
        <version>${struts2-version}</version>
    </dependency>
  </dependencies>


注意:properties標籤並非只能用於統一聲明依賴版本,但凡是須要統一聲明的地方均可以考慮使用properties標籤。



Maven命令

全局命令

  • maven -v :查看版本

工程級命令

如下命令針對於maven工程,必須到pom.xml目錄才能執行命令

  • mvn clean:清理以前編譯出的class文件,至關於清理target目錄及其目錄下的全部文件。
  • mvn compile:編譯主程序,效果是把src/main/java下的java源文件編譯爲class文件並輸出到target下的classes目錄下。
  • mvn test-compile:編譯測試程序
  • mvn test:執行src/test/java下的單元測試類,會打印出測試結果(若是被junit標識成測試類的話),並把src/main/java下的java源文件編譯爲class文件並輸出到target下的test-classes目錄下。
  • mvn package:打包,java項目打包成jar包,web項目打包成war包。打包的文件存儲到target目錄下。
  • mvn install:安裝,把maven工程打包成jar包或war包並保存到本地倉庫中。【在本地倉庫目錄下根據座標來生成包路徑來保存】。對於咱們本身的maven工程,可使用mvn install把它安裝到倉庫中。

命令生命週期

  • 屬於同一個生命週期的指令,當後面的命令執行時,前面的命令也會自動執行。
  • 常見命令週期:
    • clean :在進行真正構建以前的一些清理工做。
      • 包含命令:pre-clean,clean,post-clean
    • default:構建的核心部分:編譯、測試、打包、部署等等。【要注意,大部分命令都處於default生命週期,因此執行某個命令時,生命週期前面的命令也會自動執行。】
      • 包含命令:validate,compile,test,package,verify,install,deploy....
    • site:生成項目報告、站點、發佈站點。。
      • 包含命令:pre-site,site,post-site,site-deploy

每個階段都有一個對應的命令,且有相應的插件來支持命令的運行。


setting.xml配置文件

倉庫配置

本地倉庫配置

maven安裝路徑下\conf\settings.xml文件,在settings.xml中配置localResposity標籤。,它是被註釋了的,有配置方法的提示。

默認目錄:用戶目錄下.m2/repository

添加遠程倉庫

<mirrors>
    <!-- 中央倉庫1 -->
        <mirror>
            <id>repo1</id>
            <mirrorOf>central</mirrorOf>
            <name>Human Readable Name for this Mirror.</name>
            <url>http://repo1.maven.org/maven2/</url>
        </mirror>

        <!-- 中央倉庫2 -->
        <mirror>
            <id>repo2</id>
            <mirrorOf>central</mirrorOf>
            <name>Human Readable Name for this Mirror.</name>
            <url>http://repo2.maven.org/maven2/</url>
        </mirror>
</mirrors>

Eclipse中使用maven

配置maven

eclipse有自帶的maven插件,但不建議使用。

把獨立的maven添加成一個新的maven:

配置user settings:

建立maven工程:

【maven model用於分模塊開發時建立子工程,多個子工程與核心工程組成一個完整的項目。】

新建工程->選擇maven project

下面給的是打包方式爲war的時候的目錄結構:

修改JRE版本:

默認狀況下,maven工程引用的jre庫是1.5的,這可能會致使一些語法問題(例如泛型的語法問題),因此一般須要更改這個引用的jre庫版本。

  • 修改方法:在setting.xml中修改profiles標籤
<profile>
            <id>jdk18</id>
            <activation>
                <activeByDefault>true</activeByDefault>
                <jdk>1.8</jdk>
            </activation>
            <properties> 
                <maven.compiler.source>1.8</maven.compiler.source>  
                <maven.compiler.target>1.8</maven.compiler.target>  
                <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
                <maven.compiler.encoding>utf-8</maven.compiler.encoding>
            </properties>
</profile>

導入依賴

  • 方式一:手動添加,經過手動拷貝等方式統一增長。能夠百度包名+maven來查找依賴信息的寫法,拷貝下來粘貼到pom.xml中便可。

    • <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>3.1.0</version>
          <scope>provided</scope>
      </dependency>
  • 方式二:在eclipse,雙擊打開pom.xml,默認狀況下不是xml界面,點擊下面的dependencies選項,再點擊add,在中間的搜索框輸入信息搜索依賴,選擇依賴包,最後點擊確認。這要求你比較熟悉須要哪些包。

1539015718240

1539015941160

添加插件

有時候咱們但願給maven工程添加額外的插件,例如tomcat7:run插件,這個插件能使得咱們的工程虛擬地部署到tomcat中。

  • mvn tomcat:run 命令是一個插件,須要添加才能執行這條命令,添加方式:項目右鍵選擇maven,再add plugin,而後搜索tomcat

    • <!--build與dependencies是同一級的 -->
      <build>
          <plugins>
              <plugin>
                  <groupId>org.apache.tomcat.maven</groupId>
                  <artifactId>tomcat7-maven-plugin</artifactId>
                  <version>2.2</version>
              </plugin>
              <configuration>
              <!-- 端口 -->
              <port>8080</port>
              <!-- 訪問路徑 -->
              <path>/helloworld</path>
              <!-- 編碼 -->
              <uriEncoding>utf-8</uriEncoding>
          </configuration>
          </plugins>
      </build>

這裏僅僅給一個添加插件的示例,其餘的插件有興趣能夠自查。

Eclipse中執行maven命令

工程右鍵->run as ->第一個maven build可讓你選擇以前執行過的命令來執行,第二個maven build可讓你輸入指定命令來執行(在goals中輸入命令,mvn test只須要輸入test便可);至於後面的clean,install和test的意思已經顯而易見了。

建立web工程

若是想建立一個web工程,須要在建立工程的時候打包方式改爲war。但默認狀況下src/main下是沒有webapp目錄(存放WEB-INF目錄和web.xml的目錄)的。

  • 生成webapp目錄:
    • 方式一: WEB-INF目錄和web.xml,javaEE tools->Generate Deploy...
    • 方式二:手動建立目錄和文件

依賴範圍衝突問題:

什麼是依賴範圍衝突呢?這涉及到依賴範圍問題,主要是provided問題。以servlet-api依賴爲例,這個依賴tomcat會提供給咱們部署的項目,但若是咱們添加這個依賴的時候選擇了compile,那麼這個依賴也會帶到部署的項目中,使得存在了兩個servlet-api依賴。

解決方法:這時候要修改servlet-api依賴的範圍,改爲provided。

依賴排除問題:

這個在pom配置的依賴排除中講過了。這裏只提一下,再也不演示。

如何運行項目

java項目:

  • 運行方式一:項目右鍵->run as->java application
  • 因爲方式二跟直接到目標目錄執行java沒什麼區別,因此這裏不講,有興趣能夠自查mvn exec

web項目:

  • 部署方式一:在添加了插件以後,使用tomcat插件部署:mvn tomcat7:run
    • 選擇5 Maven build以後,輸入命令tomcat7:run
    • 區別:插件的是虛擬環境,會比較快。
  • 部署方式二:打成war包以後,把war包拷貝到tomcat目錄中。
  • 部署方式三:創建服務器以後,把項目添加到tomcat中;或者在pom.xml文件點擊右鍵,直接把項目添加到tomcat中。

工程拆分和聚合

  • 在一個比較大的項目開發協做中,若是按照之前的開發的話,是一個工程。這樣會有一些問題。拆分、分模塊便於測試和開發。不一樣開發者僅僅面向本身的工程。
  • 而後在整合的時候,把工程聚合起來,就能聚合成一個完整的項目了。

工程的拆分

工程的拆分是建立一個核心父工程,而後建立多個子模塊的狀況。核心父工程通常不會編寫什麼內容,通常只做爲依賴的彙總(讓父工程引入共有依賴,子工程單獨依賴的單獨引入)。

建立父工程:

建立子工程

爲了讓父工程能管理到子工程,因此在父工程下右鍵"new-->maven module"

建立完父工程和子模塊後,能夠在父工程的pom.xml中看到父工程管理到了子模塊:

而子模塊也指向了父工程:

而後子模塊怎麼開發呢?它至關於與一個獨立的模塊,因此你能夠像往常同樣開發。不過提一下的是,可能會發生service層調用dao層,那麼這怎麼實現呢?這就須要咱們在service層中添加dao層的依賴了,這樣service層就能夠調用dao層的方法了。

這裏提一下工程拆分與框架整合的問題,在之前一個工程中,dao和service都是交給spring去管理的,那麼如今
該怎麼處理呢?首先,要注意的是,只要咱們配置了spring(這裏注意,依賴已經導入了),不管是xml仍是註解
式,那麼spring就可以管理好咱們的bean。因此,咱們如今其實只須要關心咱們的bean是否交給了spring來管理
便可。而這個單個模塊的測試能夠在test目錄下再編寫代碼來測試。

工程的聚合

拆分工程以後,開發完成了,怎麼聚合使用呢?
首先,要注意父工程管理着子模塊,

若是打包父工程,那麼子工程也會進行打包。

而一般咱們在進行web開發的時候,因爲子模塊web是核心項目,而子模塊web又依賴着子模塊service,而在打包的時候依賴的包也會打成jar包,因此打包子模塊web的時候,web工程的lib裏面是有依賴的兄弟工程的,因此咱們能夠直接運行web工程便可。【這是運行war包的狀況】

咱們也能夠選擇在IDE中直接運行子模塊web(在eclipse直接run as),也是可以調用到其餘兄弟模塊的功能的。


寫在最後

這篇關於maven的博文看完了,你應該能對maven的使用有一個基本的瞭解。

這裏給一個經常使用的查maven的依賴信息的網站:mvnrepository.com

相關文章
相關標籤/搜索