走進JavaWeb技術世界12:從手動編譯打包到項目構建工具Maven

本系列文章將整理到我在GitHub上的《Java面試指南》倉庫,更多精彩內容請到個人倉庫裏查看html

https://github.com/h2pl/Java-Tutorial前端

喜歡的話麻煩點下Star哈java

文章首發於個人我的博客:python

www.how2playlife.comgit

本文是微信公衆號【Java技術江湖】的《走進JavaWeb技術世界》其中一篇,本文部份內容來源於網絡,爲了把本文主題講得清晰透徹,也整合了不少我認爲不錯的技術博客內容,引用其中了一些比較好的博客文章,若有侵權,請聯繫做者。程序員

該系列博文會告訴你如何從入門到進階,從servlet到框架,從ssm再到SpringBoot,一步步地學習JavaWeb基礎知識,並上手進行實戰,接着瞭解JavaWeb項目中常常要使用的技術和組件,包括日誌組件、Maven、Junit,等等內容,以便讓你更完整地瞭解整個JavaWeb技術體系,造成本身的知識框架。github

若是對本系列文章有什麼建議,或者是有什麼疑問的話,也能夠關注公衆號【Java技術江湖】聯繫做者,歡迎你參與本系列博文的創做和修訂。面試

文末贈送8000G的Java架構師學習資料,須要的朋友能夠到文末了解領取方式,資料包括Java基礎、進階、項目和架構師等免費學習資料,更有數據庫、分佈式、微服務等熱門技術學習視頻,內容豐富,兼顧原理和實踐,另外也將贈送做者原創的Java學習指南、Java程序員面試指南等乾貨資源) spring

maven簡介

1.1 Maven是什麼

Maven是一個項目管理和綜合工具。 Maven提供了開發人員構建一個完整的生命週期框架。開發者團隊能夠自動完成項目的基礎工具建設, Maven使用標準的目錄結構和默認構建生命週期。sql

在多個開發者團隊環境時, Maven能夠設置按標準在很是短的時間裏完成配置工做。 因爲大部分項目的設置都很簡單, 而且可重複使用, Maven讓開發人員的工做更輕鬆, 同時建立報表, 檢查, 構建和測試自動化設置。

用過GitHub的同窗看到這裏應該感受似曾相識,對,Maven和git的做用很類似,都是爲了方便項目的建立與管理。

歸納地說, Maven簡化和標準化項目建設過程。 處理編譯, 分配, 文檔, 團隊協做和其餘任務的無縫鏈接。 Maven增長可重用性並負責創建相關的任務。

1.2 Maven發展史

Maven設計之初, 是爲了簡化Jakarta Turbine項目的建設。 在幾個項目, 每一個項目包含了不一樣的Ant構建文件。 JAR檢查到CVS。 Apache組織開發Maven能夠創建多個項目, 發佈項目信息, 項目部署, 在幾個項目中JAR文件提供團隊合做和幫助。

Maven的經歷了Maven-> Maven2 -> Maven3的發展。

1.3 爲何要用Maven

Maven以前咱們常用Ant來進行Java項目的構建, 而後Ant僅是一個構建工具, 它並未對項目的中的工程依賴以及項目自己進行管理, 而且Ant做爲構建工具未能消除軟件構建的重複性, 由於不一樣的項目須要編寫對應的Ant任務。

Maven做爲後來者, 繼承了Ant的項目構建功能, 而且提供了依賴關係, 項目管理的功能, 所以它是一個項目管理和綜合工具, 其核心的依賴管理, 項目信息管理, 中央倉庫, 約定大於配置的核心功能使得Maven成爲當前Java項目構建和管理工具的標準選擇。

學習Maven的理由是很是多:

主流IDE(Eclipse,IDEA,Netbean) 夠內置了Maven

SpringFramework已經再也不提供jar的下載, 直接經過Maven進行依賴下載。

在github, 開源社區幾乎全部流行的Java項目都是經過Maven進行構建和管理的。

Maven 新手入門

Maven概念

Maven做爲一個構建工具,不只能幫咱們自動化構建,還可以抽象構建過程,提供構建任務實現;它跨平臺,對外提供了一致的操做接口,這一切足以使它成爲優秀的、流行的構建工具。

Maven不只是構建工具,仍是一個依賴管理工具和項目管理工具,它提供了中央倉庫,能幫我自動下載構件。

maven的安裝

一:由於本人是window系統,因此這裏只介紹window下如何安裝,在安裝Maven以前,先確認已經安裝了JDK.![image.png](http://upload-images.jianshu.io/upload_images/5811881-5a7737962f83f677.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 "image.png")

二:接着去Maven官網下載界面下載想要的版本解壓到你想要的目錄就行![image.png](http://upload-images.jianshu.io/upload_images/5811881-16d9fd82c7f938ae.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 "image.png")

![image.png](http://upload-images.jianshu.io/upload_images/5811881-7482108a7ff71031.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 "image.png")

三:最後設置一下環境變量,將Maven安裝配置到操做系統環境中,主要就是配置M2_HOME 和PATH兩項,如圖![image.png](http://upload-images.jianshu.io/upload_images/5811881-ffdf167e64415703.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 "image.png")

都搞定後,驗證一下,打開doc輸入 mvn -v如何獲得下面信息就說明配置成功了![image.png](http://upload-images.jianshu.io/upload_images/5811881-c473853017951ebe.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 "image.png")

maven目錄

![image.png](http://upload-images.jianshu.io/upload_images/5811881-8a4c77bcc9a4565a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 "image.png")

  • bin目錄:
    該目錄包含了mvn運行的腳本,這些腳本用來配置java命令,準備好classpath和相關的Java系統屬性,而後執行Java命令。
  • boot目錄:
    該目錄只包含一個文件,該文件爲plexus-classworlds-2.5.2.jar。plexus-classworlds是一個類加載器框架,相對於默認的java類加載器,它提供了更加豐富的語法以方便配置,Maven使用該框架加載本身的類庫。
  • conf目錄:
    該目錄包含了一個很是重要的文件settings.xml。直接修改該文件,就能在機器上全局地定製Maven的行爲,通常狀況下,咱們更偏向於複製該文件至~/.m2/目錄下(~表示用戶目錄),而後修改該文件,在用戶範圍定製Maven的行爲。
  • lib目錄:
    該目錄包含了全部Maven運行時須要的Java類庫,Maven自己是分模塊開發的,所以用戶能看到諸如maven-core-3.0.jar、maven-model-3.0.jar之類的文件,此外這裏還包含一些Maven用到的第三方依賴如commons-cli-1.2.jar、commons-lang-2.6.jar等等。

Maven經常使用命令說明

mvn clean:表示運行清理操做(會默認把target文件夾中的數據清理)。
    mvn clean compile:表示先運行清理以後運行編譯,會將代碼編譯到target文件夾中。
    mvn clean test:運行清理和測試。
    mvn clean package:運行清理和打包。
    mvn clean install:運行清理和安裝,會將打好的包安裝到本地倉庫中,以便其餘的項目能夠調用。
    mvn clean deploy:運行清理和發佈(發佈到私服上面)。複製代碼

上面的命令大部分都是連寫的,你們也能夠拆分分別執行,這是活的,看我的喜愛以及使用需求,Eclipse Run as對maven項目會提供經常使用的命令。

Maven使用

<?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.tengj</groupId>
        <artifactId>springBootDemo1</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>springBootDemo1</name>
    </project>
複製代碼

代碼的第一行是XML頭,指定了該xml文檔的版本和編碼方式。project是全部pom.xml的根元素,它還聲明瞭一些POM相關的命名空間及xsd元素。根元素下的第一個子元素modelVersion指定了當前的POM模型的版本,對於Maven3來講,它只能是4.0.0代碼中最重要是包含了groupId,artifactId和version了。這三個元素定義了一個項目基本的座標,在Maven的世界,任何的jar、pom或者jar都是以基於這些基本的座標進行區分的。

groupId定義了項目屬於哪一個組,隨意命名,好比谷歌公司的myapp項目,就取名爲 com.google.myapp

artifactId定義了當前Maven項目在組中惟一的ID,好比定義hello-world。

version指定了項目當前的版本0.0.1-SNAPSHOT,SNAPSHOT意爲快照,說明該項目還處於開發中,是不穩定的。

name元素生命了一個對於用戶更爲友好的項目名稱,雖然這不是必須的,但仍是推薦爲每一個POM聲明name,以方便信息交流

%E4%BE%9D%E8%B5%96%E7%9A%84%E9%85%8D%E7%BD%AE "依賴的配置")依賴的配置

<project>
    ...
    <dependencies>
        <dependency>
            <groupId>實際項目</groupId>
         <artifactId>模塊</artifactId>
         <version>版本</version>
         <type>依賴類型</type>
         <scope>依賴範圍</scope>
         <optional>依賴是否可選</optional>
         <!—主要用於排除傳遞性依賴-->
         <exclusions>
             <exclusion>
               <groupId>…</groupId>
              <artifactId>…</artifactId>
           </exclusion>
         </exclusions>
      </dependency>
    <dependencies>
    ...
    </project>複製代碼

根元素project下的dependencies能夠包含一個或者多個dependency元素,以聲明一個或者多個項目依賴。每一個依賴能夠包含的元素有:

  • grounpId、artifactId和version:以來的基本座標,對於任何一個依賴來講,基本座標是最重要的,Maven根據座標才能找到須要的依賴。
  • type:依賴的類型,對於項目座標定義的packaging。大部分狀況下,該元素沒必要聲明,其默認值爲jar
  • scope:依賴的範圍
  • optional:標記依賴是否可選
  • exclusions:用來排除傳遞性依賴
%E4%BE%9D%E8%B5%96%E8%8C%83%E5%9B%B4 "依賴範圍")依賴範圍

依賴範圍就是用來控制依賴和三種classpath(編譯classpath,測試classpath、運行classpath)的關係,Maven有以下幾種依賴範圍:

  • compile:編譯依賴範圍。若是沒有指定,就會默認使用該依賴範圍。使用此依賴範圍的Maven依賴,對於編譯、測試、運行三種classpath都有效。典型的例子是spring-code,在編譯、測試和運行的時候都須要使用該依賴。
  • test: 測試依賴範圍。使用次依賴範圍的Maven依賴,只對於測試classpath有效,在編譯主代碼或者運行項目的使用時將沒法使用此依賴。典型的例子是Jnuit,它只有在編譯測試代碼及運行測試的時候才須要。
  • provided:已提供依賴範圍。使用此依賴範圍的Maven依賴,對於編譯和測試classpath有效,但在運行時候無效。典型的例子是servlet-api,編譯和測試項目的時候須要該依賴,但在運行項目的時候,因爲容器以及提供,就不須要Maven重複地引入一遍。
  • runtime:運行時依賴範圍。使用此依賴範圍的Maven依賴,對於測試和運行classpath有效,但在編譯主代碼時無效。典型的例子是JDBC驅動實現,項目主代碼的編譯只須要JDK提供的JDBC接口,只有在執行測試或者運行項目的時候才須要實現上述接口的具體JDBC驅動。
  • system:系統依賴範圍。該依賴與三種classpath的關係,和provided依賴範圍徹底一致,可是,使用system範圍的依賴時必須經過systemPath元素顯示地指定依賴文件的路徑。因爲此類依賴不是經過Maven倉庫解析的,並且每每與本機系統綁定,可能構成構建的不可移植,所以應該謹慎使用。systemPath元素能夠引用環境變量,如:
<dependency>
        <groupId>javax.sql</groupId>
        <artifactId>jdbc-stdext</artifactId>
        <Version>2.0</Version>
        <scope>system</scope>
        <systemPath>${java.home}/lib/rt.jar</systemPath>
    </dependency>複製代碼
  • import:導入依賴範圍。該依賴範圍不會對三種classpath產生實際的影響。
    上述除import之外的各類依賴範圍與三種classpath的關係以下:

![image.png](http://upload-images.jianshu.io/upload_images/5811881-e7cdb7800f523b6b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 "image.png")

傳遞性依賴

好比一個account-email項目爲例,account-email有一個compile範圍的spring-code依賴,spring-code有一個compile範圍的commons-logging依賴,那麼commons-logging就會成爲account-email的compile的範圍依賴,commons-logging是account-email的一個傳遞性依賴

有了傳遞性依賴機制,在使用Spring Framework的時候就不用去考慮它依賴了什麼,也不用擔憂引入多餘的依賴。Maven會解析各個直接依賴的POM,將那些必要的間接依賴,以傳遞性依賴的形式引入到當前的項目中。

依賴範圍

假設A依賴於B,B依賴於C,咱們說A對於B是第一直接依賴,B對於C是第二直接依賴,A對於C是傳遞性依賴。第一直接依賴和第二直接依賴的範圍決定了傳遞性依賴的範圍,以下圖所示,最左邊一行表示第一直接依賴範圍,最上面一行表示第二直接依賴範圍,中間的交叉單元格則表示傳遞依賴範圍。

![image.png](http://upload-images.jianshu.io/upload_images/5811881-9e1e45b117656aac.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240 "image.png")

從上圖中,咱們能夠發現這樣的規律:

  • 當第二直接依賴的範圍是compile的時候,傳遞性依賴的範圍與第一直接依賴的範圍一致;
  • 當第二直接依賴的範圍是test的時候,依賴不會得以傳遞;
  • 當第二直接依賴的範圍是provided的時候,只傳遞第一直接依賴範圍也爲provided的依賴,切傳遞依賴的範圍一樣爲provided;
  • 當第二直接依賴的範圍是runtime的時候,傳遞性依賴的範圍與第一直接依賴的範圍一致,但compile列外,此時傳遞性依賴範圍爲runtime.

Maven和Gradle的比較

Java生態體系中有三大構建工具:Ant、Maven和Gradle。其中,Ant是由Apache軟件基金會維護;Maven這個單詞來自於意第緒語(猶太語),意爲知識的積累,最初在Jakata Turbine項目中用來簡化構建過程;Gradle是一個基於Apache Ant和Apache Maven概念的項目自動化構建開源工具,它使用一種基於Groovy的特定領域語言(DSL)來聲明項目設置,拋棄了基於XML的各類繁瑣配置。

通過幾年的發展,Ant幾乎銷聲匿跡,而Maven因爲較爲不靈活的配置也漸漸被遺忘,而因爲Gradle是基於Ant和Maven的一個優化版本,變得如日中天。

Maven的主要功能主要分爲依賴管理系統、多模塊構建、一致的項目結構、一致的構建模型和插件機制。這裏經過這五個方面介紹二者的不一樣:

依賴管理系統

在Maven的管理體系中,用GroupID、ArtifactID和Version組成的Coordination惟一標識一個依賴項。任何基於Maven構建的項目自身也必須定義這三項屬性,生成的包能夠是Jar包,也能夠是War包或Ear包。

一個典型的引用以下:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        spring-boot-starter-data-jpa
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        spring-boot-starter-thymeleaf
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        spring-boot-starter-test
        <scope>test</scope>
    </dependency>
</dependencies>
複製代碼

這裏 GroupID相似於C#中的namespace或者Java中的package,而ArtifactID至關於Class,Version至關於不一樣版本,若是Version忽略掉,將選擇最新的版本連接。

同時,存儲這些組件的倉庫有遠程倉庫和本地倉庫之分,遠程倉庫能夠是使用世界公用的central倉庫,也可使用Apache Nexus自建的私有倉庫;本地倉庫則在本地計算機上。經過Maven安裝目錄下的settings.xml文件能夠配置本地倉庫的路徑,以及採用的遠程倉庫地址。Gradle在設計時沿用了Maven這種依賴管理體系,同時也引入了改進,讓依賴變得更加簡潔:

dependencies {
    // This dependency is exported to consumers, that is to say found on their compile classpath.
    api 'org.apache.commons:commons-math3:3.6.1'
    複製代碼
// This dependency is used internally, and not exposed to consumers on their own compile classpath.
    implementation 'com.google.guava:guava:23.0'複製代碼
// Use JUnit test framework
    testImplementation 'junit:junit:4.12'複製代碼
compile 'org.hibernate:hibernate-core:3.6.7.Final'
    testCompile ‘junit:junit:4.+'
    
    複製代碼
}複製代碼

另外,Maven和Gradle對依賴項的審視也有所不一樣。在Maven中,一個依賴項有6種scope,分別是compile、provided、runtime、test、system、import。其中compile爲默認。而gradle將其簡化爲4種,compile、runtime、testCompile、testRuntime。如上述代碼「testCompile ‘junit:junit:4.+'」,在Gradle中支持動態的版本依賴,在版本號後面使用+號能夠實現動態的版本管理。在解決依賴衝突方面Gradle的實現機制更加明確,二者都採用的是傳遞性依賴,而若是多個依賴項指向同一個依賴項的不一樣版本時可能會引發依賴衝突,Maven處理起來較爲繁瑣,而Gradle先天具備比較明確的策略。

多模塊構建

在面向服務的架構中,一般將一個項目分解爲多個模塊。在Maven中須要定義parent POM(Project Object Model)做爲一組module的通用配置模型,在POM文件中可使用 標籤來定義一組子模塊。parent POM中的build配置以及依賴配置會自動繼承給子module。

Gradle也支持多模塊構建,在parent的build.gradle中可使用allprojects和subprojects代碼塊分別定義應用於全部項目或子項目中的配置。對於子模塊中的定義放置在settings.gradle文件中,每個模塊表明project的對象實例,在parent的build.gradle中經過allproject或subprojects對這些對象進行操做,相比Maven更顯靈活。

allprojects {
    task nice << { task -> println "I'm $task.project.name" }
    }複製代碼

執行命令gradle -q nice會依次打印出各模塊的項目名稱。

一致的項目結構

Maven指定了一套項目目錄結構做爲標準的java項目結構,Gradle也沿用了這一標準的目錄結構。若是在Gradle項目中使用了Maven項目結構的話,在Gradle中無需進行多餘的配置,只需在文件中包括apply plugin:'java',系統會自動識別source、resource、test source、test resource等相應資源。

同時,Gradle做爲JVM上的構建工具,也支持Groovy、Scala等源代碼的構建,一樣功能Maven經過一些插件也能達到目的,但配置方面Gradle更靈活。

一致的構建模型

爲了解決Ant中對項目構建缺少標準化的問題,Maven設置了標準的項目週期,構建週期:驗證、初始化、生成原始數據、處理原始數據、生成資源、處理資源、編譯、處理類、生成測試原始數據、處理測試原始數據、生成測試資源、處理測試資源、測試編譯、處理測試類、測試、預約義包、生成包文件、預集成測試、集成測試、後集成測試、覈實、安裝、部署。但這種構建週期也是Maven應用的劣勢。由於Maven將項目的構建週期限制過嚴,沒法在構建週期中添加新的階段,只能將插件綁定到已有的階段上。而Gradle在構建模型上很是靈活,能夠建立一個task,並隨時經過depends創建與已有task的依賴關係。

插件機制

二者都採用了插件機制,Maven是基於XML進行配置,而在Gradle中更加靈活。

參考文章

http://www.pianshen.com/article/4537698845https://www.jianshu.com/p/7248276d3bb5https://www.cnblogs.com/lykbk/p/erwerwerwerwerwerwe.htmlhttps://blog.csdn.net/u012131888/article/details/78209514https://blog.csdn.net/belvine/article/details/81073365https://blog.csdn.net/u012131888/article/details/78209514

微信公衆號

我的公衆號:程序員黃小斜

​黃小斜是 985 碩士,阿里巴巴Java工程師,在自學編程、技術求職、Java學習等方面有豐富經驗和獨到看法,但願幫助到更多想要從事互聯網行業的程序員們。​做者專一於 JAVA 後端技術棧,熱衷於分享程序員乾貨、學習經驗、求職心得,以及自學編程和Java技術棧的相關乾貨。​黃小斜是一個斜槓青年,堅持學習和寫做,相信終身學習的力量,但願和更多的程序員交朋友,一塊兒進步和成長!

原創電子書:關注微信公衆號【程序員黃小斜】後回覆【原創電子書】便可領取我原創的電子書《菜鳥程序員修煉手冊:從技術小白到阿里巴巴Java工程師》這份電子書總結了我2年的Java學習之路,包括學習方法、技術總結、求職經驗和麪試技巧等內容,已經幫助不少的程序員拿到了心儀的offer!

程序員3T技術學習資源: 一些程序員學習技術的資源大禮包,關注公衆號後,後臺回覆關鍵字 「資料」 便可免費無套路獲取,包括Java、python、C++、大數據、機器學習、前端、移動端等方向的技術資料。

技術公衆號:Java技術江湖

若是你們想要實時關注我更新的文章以及分享的乾貨的話,能夠關注個人微信公衆號【Java技術江湖】

這是一位阿里 Java 工程師的技術小站。做者黃小斜,專一 Java 相關技術:SSM、SpringBoot、MySQL、分佈式、中間件、集羣、Linux、網絡、多線程,偶爾講點Docker、ELK,同時也分享技術乾貨和學習經驗,致力於Java全棧開發!

Java工程師必備學習資源:關注公衆號後回覆」Java「便可領取 Java基礎、進階、項目和架構師等免費學習資料,更有數據庫、分佈式、微服務等熱門技術學習視頻,內容豐富,兼顧原理和實踐,另外也將贈送做者原創的Java學習指南、Java程序員面試指南等乾貨資源

個人公衆號


微信公衆號

我的公衆號:程序員黃小斜

​黃小斜是 985 碩士,阿里巴巴Java工程師,在自學編程、技術求職、Java學習等方面有豐富經驗和獨到看法,但願幫助到更多想要從事互聯網行業的程序員們。​做者專一於 JAVA 後端技術棧,熱衷於分享程序員乾貨、學習經驗、求職心得,以及自學編程和Java技術棧的相關乾貨。​黃小斜是一個斜槓青年,堅持學習和寫做,相信終身學習的力量,但願和更多的程序員交朋友,一塊兒進步和成長!

原創電子書:關注微信公衆號【程序員黃小斜】後回覆【原創電子書】便可領取我原創的電子書《菜鳥程序員修煉手冊:從技術小白到阿里巴巴Java工程師》這份電子書總結了我2年的Java學習之路,包括學習方法、技術總結、求職經驗和麪試技巧等內容,已經幫助不少的程序員拿到了心儀的offer!

程序員3T技術學習資源: 一些程序員學習技術的資源大禮包,關注公衆號後,後臺回覆關鍵字 「資料」 便可免費無套路獲取,包括Java、python、C++、大數據、機器學習、前端、移動端等方向的技術資料。

技術公衆號:Java技術江湖

若是你們想要實時關注我更新的文章以及分享的乾貨的話,能夠關注個人微信公衆號【Java技術江湖】

這是一位阿里 Java 工程師的技術小站。做者黃小斜,專一 Java 相關技術:SSM、SpringBoot、MySQL、分佈式、中間件、集羣、Linux、網絡、多線程,偶爾講點Docker、ELK,同時也分享技術乾貨和學習經驗,致力於Java全棧開發!

Java工程師必備學習資源:關注公衆號後回覆」Java「便可領取 Java基礎、進階、項目和架構師等免費學習資料,更有數據庫、分佈式、微服務等熱門技術學習視頻,內容豐富,兼顧原理和實踐,另外也將贈送做者原創的Java學習指南、Java程序員面試指南等乾貨資源

個人公衆號

相關文章
相關標籤/搜索