Maven學習筆記

maven學習筆記

先生,您在寫代碼嗎? 不,咱們正在完成一項偉大的工程。

前言


在剛學maven時,我就把maven看成一個引入jar包的工具而已,之前是本身下載jar包,如今是隻用在pom文件中填寫相應的座標就能夠了。除此以外當咱們須要使用的jar包依賴於另外一個jar包時,maven會自動幫咱們引入適用的版本。這就避免了咱們本身下jar包,而後版本不匹配的問題。除此以外,我還模糊的知道一些maven的聚合和繼承,以後在接手項目的時候仍是吃了的大虧。因而打算從新學習一下maven。java

maven是什麼?


Apache Maven is a software project management and comprehension tool. Based on the concept of a project object model (POM), Maven can manage a project's build, reporting and documentation from a central piece of information.
comprehension: the ability to understand something 理解力
maven是一種軟件項目管理和理解的工具。基於項目對象模型的概念。程序員

可是在後面的what is maven? 我看到這麼一句話:web

We hope that we have created something that will make the day-to-day work of Java developers easier and generally help with the comprehension of any Java-based project.
咱們但願咱們編寫的這個工具可以使得java程序員的工做變得簡單,使得任何使用該工具的任何java工程更加容易理解。

爲何可以幫助開發人員理解工程?

Maven約定了目錄架構apache

clipboard.png

若是你在java中放配置文件,極可能會報找不到文件的異常。
可是我就是想在java這個文件夾中放配置文件,該怎麼辦呢? 你須要在pom文件中聲明一下
<build>api

<!--配置可在rc/main/java文件夾下編譯出xml文件-->


<resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

Maven的定位

多數博客或者視頻都將maven定義爲自動化構建工具。
那什麼是自動化構建工具呢?
咱們首先來解釋構建:服務器

    • 編譯架構

      • 將java源文件變成字節碼,交給JVM去執行
    • 部署框架

      • 一個BS項目最終運行的並非動態web工程自己,而是這個動態web工程「編譯的結果」
  • 構建各個過程的步驟:maven

    • 清理: 將之前編譯獲得的舊字節碼刪除掉
    • 編譯: 將java源代碼變成字節碼
    • 測試: 執行test文件夾中的測試程序
    • 報告: 顯示測試程序執行的結果
    • 打包: 動態Web工程打成war包,Java工程打成jar包
    • 安裝: Maven的特定概念---將打包獲得的文件複製到"倉庫"中指定的位置
    • 部署: 將動態Web工程生成的war包複製到Servlet容器中指定的目錄下,使其能夠運行
  • 自動化構建,其實上述步驟,在elipse和IDEA中也能夠完成,只不過沒那麼標準。既然IDE已經能夠完成這些工做了,那麼還要maven幹什麼呢?
    平常開發中,如下幾個步驟是咱們常常走的:ide

    • 編譯
    • 打包
    • 部署
    • 測試

這幾個步驟是程式化的,沒有太大的變數或者說根本就沒有變數。程序員們很但願從這些重複的工做中脫身出來,將這些重複的工做交給工具去作。此時Maven的意義就體現出來了,它能夠自動的從構建過程當中的起點一直執行到終點。

maven的核心概念

  1. POM
  2. 座標
  3. 依賴
  4. 倉庫
  5. 生命週期/插件/目標
  6. 繼承
  7. 聚合

POM

POM: a project object model.項目對象模型

對這個概念老實說,我並無很深的理解,或者說我並不理解項目對象模型的意思。
有資料說項目對象模型就是將Java工程的相關信息封裝爲對象便於操做和管理的模型。
這個解釋的稍微讓人那麼容易那麼一點。
學習Maven就是學習pom.xml文件中的配置

座標

座標這個概念我以爲和依賴結合起來解釋會更好,在沒有Maven以前,咱們引入jar包的方式就是先下載,而後在複製在類文件路徑下,你的項目須要的jar包,在Maven看來就是你的項目依賴於某些jar包,pom.xml文件中填寫對應jar包的位置,就能夠引入對應的jar包

使用以下三個向量在 Maven 的倉庫中惟一的肯定一個 Maven 工程。

[1] groupid:公司或組織的域名倒序+當前項目名稱
[2] artifactId:當前項目的模塊名稱
[3] version:當前模塊的版本

    <groupId>com.atguigu.maven</groupId>
    <artifactId>Hello</artifactId>
    <version>0.0.1-SNAPSHOT</version>

clipboard.png

其實引入對象的依賴很是的簡單,咱們只用去Maven的中央倉庫,輸入jar包的名字,選擇你須要的版本,而後將複製倉庫給出的依賴,粘貼在pom.xml文件中的dependencies標籤下就能夠了.
步驟以下:
百度搜索Maven

clipboard.png

進入以後

clipboard.png

好比說我想要Spring-test的jar包

clipboard.png

而後選擇對應的版本:

clipboard.png

clipboard.png

倉庫

倉庫能夠理解爲存放jar包的地方。

    1. 倉庫的分類
    • 本地倉庫:當前電腦上的部署的倉庫目錄,爲當前電腦上的全部Maven工程服務
    • 遠程倉庫:

      (1) 私服: 搭建在局域網環境中,爲局域網範圍內的全部Maven工程服務
        (2) 中央倉庫: 架設在Internet上,爲全世界範圍內全部的Maven工程服務。
        (3) 中央倉庫鏡像: 爲了分擔中央倉庫的流量,提高用戶的訪問速度。

    使用properties標籤內自定義標籤統一聲明版本號

    生命週期/插件/目標

    什麼是Mavende生命週期?

    Maven 生命週期定義了各個構建環節的執行順序,有了這個清單,Maven 就能夠自動化的執行構建命 令了。

    Maven有三套互相獨立的生命週期:

    Clean Lifecycle 在進行真正的構建以前進行一些清理工做
    Default Lifecycle 構建的核心部分,編譯,測試,打包,安裝,部署等等。
    Site Lifecycle 生成項目報告,站點,發佈站點。

    它們是相互獨立的,你能夠僅僅調用 clean 來清理工做目錄,僅僅調用 site 來生成站點。固然你也能夠
    直接運行 mvn clean install site 運行全部這三套生命週期。
    這個生成站點的意思就是: 在本地生成有關你項目的相關信息。
    長這個樣子:

    clipboard.png

    Clean生命週期:

    Clean 生命週期一共包含了三個階段:
         1 pre-clean 執行一些須要在 clean 以前完成的工做
         2 clean 移除全部上一次構建生成的文件
         3 post-clean 執行一些須要在 clean 以後馬上完成的工做

    Site生命週期

    1 pre-site 執行一些須要在生成站點文檔以前完成的工做
    2 site 生成項目的站點文檔
    3 post-site 執行一些須要在生成站點文檔以後完成的工做,而且爲部署作準備
    4 site-deploy 將生成的站點文檔部署到特定的服務器上
    這裏常常用到的是 site 階段和 site-deploy 階段,用以生成和發佈 Maven 站點,這但是 Maven     至關強大的功能,Manager 比較喜歡,文檔及統計數據自動生成,很好看。

    Default 生命週期是 Maven 生命週期中最重要的一個,絕大部分工做都發生在這個生命週期中。這裏,
    只解釋一些比較重要和經常使用的階段:

    validate
            generate-sources
            process-sources
            generate-resources
            process-resources          複製並處理資源文件,至目標目錄,準備打包。
            compile                    編譯項目的源代碼。
            process-classes
            generate-test-sources   
            process-test-sources
            generate-test-resources
            process-test-resources          複製並處理資源文件,至目標測試目錄。
            test-compile                    編譯測試源代碼。
            process-test-classes
            test                使用合適的單元測試框架運行測試。這些測試代碼不會被打包或部署。
            prepare-package
            package          接受編譯好的代碼,打包成可發佈的格式,如  JAR  。
            pre-integration-test
            integration-test
            post-integration-test
            verify
            install          將包安裝至本地倉庫,以讓其它項目依賴。
            deploy          將最終的包複製到遠程的倉庫,以讓其它開發人員與項目共享
    1. maven生命週期(lifecycle)由各個階段組成,每一個階段由maven的插件plugin來執行完成。
    2. 當咱們執行的maven命令須要用到某些插件時,Maven的核心程序會首先到本地倉庫中查找
    3. 本地倉庫的默認位置: 能夠在配置文件中指定

    我查的資料是

    依賴

    complie

    • 對主程序是否有效:有效
    • 對測試程序是否有效: 有效
    • 是否參與打包: 參與
    • 是否參與部署: 參與
    • 典型例子: Spring-core

    test

    • 對主程序是否有效: 無效
    • 對測試程序是否有效: 有效
    • 是否參與打包: 不參與
    • 是否參與部署: 不參與
    • 典型例子: junit

    provided

    • 對主程序是否有效: 有效
    • 對測試程序是否有效: 有效
    • 是否參與打包: 不參與
    • 是否參與部署: 不參與
    • 典型例子: servlet-api.jar

    依賴傳遞性

    模塊A依賴於模塊B。
    模塊B又依賴於C模塊
    則模塊A內會有C模塊。

    讓咱們把以上的例子在通俗化一些:

    模塊C引入了Spring-corejar包,
    那麼模塊C中的Maven依賴就會有如下兩個jar包。

    clipboard.png

    模塊A引入模塊B,就會順帶把這兩個jar包一併引入。

    clipboard.png

    模塊A的pom:

    clipboard.png

    可是如今我並不想要commons-logging這個jar包該怎麼辦呢?
    咱們能夠排除依賴:

    clipboard.png

    繼承

    繼承能夠幫咱們作什麼?

    • 統一管理依賴的版本。

    一個典型的例子就是:

    如今項目下A、B、C三個模塊,三個模塊都依賴着不一樣的Junit的版本,依賴範圍爲test時,依賴又不能傳遞過來,可是咱們但願可以統一Junit版本,可能有的人天然會想到,你讓A、B、C模塊pom中的Junit依賴版本寫一致不就好了,這也是個辦法。可是maven在設計的時候估計也考慮到了這種狀況,就是繼承了。

    繼承該如何使用:

    首先你須要建立一個maven工程,注意指定打包方式爲pom    
    
    <groupId>com.cxkStudy.maven</groupId>
     <artifactId>Parent</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <description>學習Maven使用</description>
      <packaging>pom</packaging>

    再建立一個maven工程,在該模塊中指定它的父工程是誰.
    
     <parent>
            <groupId>com.cxkStudy.maven</groupId>
              <artifactId>Parent</artifactId>
              <version>0.0.1-SNAPSHOT</version>
        </parent>

    在父項目中肯定子模塊的位置
      <modules>
        <module>../studyDenpen</module>
        <module>../Hello</module>
     </modules>

    module標籤中填的是相對於父項目的位置。
    這也就是聚合了.

    爲何要使用聚合?

    將多個工程拆分爲模塊後,須要手動逐個安裝到倉庫後依賴纔可以生效。修改源碼後也須要逐個手動進
    行 clean 操做。而使用了聚合以後就能夠批量進行 Maven 工程的安裝、清理工做。

    咱們能夠在父工程裏面指定Junit的版本,在子模塊使用Junit的時候不寫版本就行了。

    父工程中執行Junit的版本:

    <dependencyManagement>
            <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.9</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    子模塊中引入Junit的時候不指定版本

    <dependency>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
       </dependency>

    請注意配置繼承後,執行安裝命令要先安裝父工程。

    隨着咱們的項目愈來愈大,src下面的包會愈來愈多,我曾經在GitHub下見過一個項目,SRC下面有三十多個包,每一個包下面又有不少類。這代碼看的我想吐,不是代碼寫的爛,而是太混雜了,結構不清晰。咱們能夠將咱們的項目根據功能進行拆分,以免src下出現太多的包。好比說,咱們能夠將某一個模塊專門用來發布咱們寫的功能模塊,某一個模塊放置公共類,某一個模塊存放業務代碼。這樣在結構上會更爲清晰,但這隻用於比較大的工程,小的工程採用如此的拆分仍是得不償失。

    相關文章
    相關標籤/搜索