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

小李的Build之路(上)

轉自: 劉欣 碼農翻身 2016-07-10html

  • 摘要:手工Build的煩惱要不是爲了和女友留在一個城市,小李確定去北上廣奮鬥去了。如今他只能留在這個2.5線城市,進入這家軟件開發公司,7,8我的,10來條槍,是個典型的軟件小做坊。上班第一天,CTO兼架構師兼項目經理兼開發組長老張把小李叫去,諄諄教導說:「小李啊,我看了你的簡歷,我對你在公司的發展仍是挺看好的,不過做爲新人,你對新業務還不熟悉,無法開發核心系統,這段時間,你要一邊學習,一邊幫着項目作個很重要的工做:Build「小李心說你還給我拽英語啊,雖然內心這麼想,小李仍是不
  • 手工Build的煩惱

    要不是爲了和女友留在一個城市,小李確定去北上廣奮鬥去了。前端

    如今他只能留在這個2.5線城市,進入這家軟件開發公司,7,8我的,10來條槍,是個典型的軟件小做坊。java

    上班第一天,CTO兼架構師兼項目經理兼開發組長老張把小李叫去,諄諄教導說:git

    「小李啊,我看了你的簡歷,我對你在公司的發展仍是挺看好的,不過做爲新人,你對新業務還不熟悉,無法開發核心系統,這段時間,你要一邊學習,一邊幫着項目作個很重要的工做:Build「程序員

    小李心說你還給我拽英語啊, 雖然內心這麼想, 小李仍是不動聲色,面帶微笑的問:github

    「這Build是什麼東西?」web

    老張說:「我很是忙, 沒時間給你解釋,這兒有個文檔,你看看就知道了」面試

    說着,老張甩給了他幾張紙 ,補充到: 「有問題問小王, 他比你早來一個月,作Build已經很熟了」算法

    小李仔細看了一遍,上面寫着:spring

    XXX公司Build 流程 (測試環境)

    (1) 設置Eclipse 工做區, 編碼爲UTF-8, java 編譯級別爲JDK 1.7

    (2) 從SVN下載最新源代碼到Eclipse工做區

    (3) 確保Eclispe工做區沒有編譯錯誤

    (4) 手工修改下面 20個 配置文件

    database.properties

    cache.properties

    user.properties

    。。。。。。

    (5) 把Eclipse中的Web項目導出成War 包

    小王還特別在這裏用紅色的筆加了標註: Web項目所依賴的其餘java項目也會被自動包含到War包的 WEB-INF/lib目錄下

    (6) 上傳到測試服務器,安裝

    (7) 作冒煙測試

    小李笑了:這不就是一個編譯,打包,部署,測試的流程嗎? 還Build !

    正在這時,開發骨幹小梁叫小李了:「小李, 我改了幾個Bug,立刻要測試,趕忙給我作一個測試環境的Build」

    小李不敢怠慢,馬上按照文檔作了一遍,花了將近半個小時才折騰完。

    但是到了最後一步,作冒煙測試的時候, 系統卻啓動不了了 !

    小李查了很久才發現,原來測試環境的JDK是1.6 , 可是Build文檔上寫的是1.7 固然跑不起來了。

    小李暗暗的罵前任小王: 你小子確定知道這裏有個坑, 怎麼不在文檔上標註出來?

    趕忙作個新的Build 放到測試環境, 此次冒煙測試順利經過了。

    剛鬆了口氣, 測試小趙就叫了起來: 「小梁, 你那個Bug 沒有修復啊」

    開發骨幹小梁本能的反應到: 「這不可能! 個人代碼本地都測試過了, 代碼也提交了「

    小梁接着把矛頭就指向小李: 「哎對了小李,你的Build是否是又搞錯了。」

    小李心頭一驚 , 趕忙去查,果真,在第4步,手工修改配置文件的時候把數據庫改錯了 ,指向了開發庫,而不是測試庫。

    趕忙改吧, 原來作Build的小王也跑過來湊熱鬧, 在前Build專員小王,開發小梁和測試小趙三雙眼睛的嚴厲注目下, 小李頭上都要冒汗了。

    還好,第三次終於成功了。 全部的測試都順利經過。

    (實際上,小李在緊張的忙碌中也忘了去更新那個文檔,把JDK 改爲1.6)

    就這樣過了一週, 小李天天都得戰戰兢兢的作四五個Build, 雖然作的愈來愈熟,出錯愈來愈少, 可是天天仍是佔用了很多時間。

    大好年華就要在Build中蹉跎了嗎, 堅定不行。

    自動化Build

    小李決定把這個手工的、費事的、容易出錯的Build給自動化起來, 未來誰要是作測試環境的Build,只要運行一個命令便可。

    用什麼語言來實現呢? 固然是Java大法好 ! 小李在大學修煉了那麼久,自認爲對OO,設計模式已經爐火純青了, 如今終於有了用武之地。

    小李白天工做, 晚上回到住處就開發這個自動化的Build, 天天干到12點才罷休。

    可是小李不以爲累, 天天都依依不捨的去上牀睡覺, 由於創造一個新工具,造福你們的想法一直激勵着本身,有時候甚至以爲很快樂。

    一個月後, 自動化工具新鮮出爐, 這實際上是一套Java 的API, 小李把它稱爲BuildTool V1.0 專門用於下載源碼,編譯,打包,部署,測試。

    例如,若是你想編譯java 代碼, 能夠這麼寫:

    小李的 Build 之路 (上)_Java

    小李對於FileSet這個抽象很得意, 它能表明一個文件集合, 既能夠是java 源文件路徑, 也能夠是 classpath 的路徑。

    其餘的API像下載源碼, 打包,部署,測試也是相似。

    如今小李真的只須要運行一個命令,就能夠爲測試環境生成一個build :

    java BuildTool test

    工做量一會兒少了好多, 而且機器運行,基本上不會出錯。

    小李由於這個自動化的BuildTool, 得到的公司的嘉獎,還漲了一點工資。

    對小李來講,這都不是最重要的, 最重要的經過設計和實現這個BuildTool, 本身的能力有了很大的提高。

    本身已經 不只僅是一個只會用SSH框架的一個HTML填空人員了!

    碼農翻身評: 大部分人只會抱怨項目很無趣,沒有挑戰, 遇到問題也只會安於現狀,

    少數人會發現工做中的「痛點」問題,而且真正動手解決它, 給公司帶來了價值, 這是提升本身, 讓本身和別人區分開來的重要方法。

    JAVA vs XML

    今年的形勢很好,公司業務發展的不錯,招了一批新人,一會兒接了3,4 個新項目, 小李主動請纓,替這些項目創建一個自動化的Build 。

    可是小李很快就發現了問題, 直接用Java語言來編寫,功能雖然能實現, 可是看起來就太繁瑣了。

    本身寫的代碼過幾天看也得思考一下才能明白。

    是本身的BuildTool API設計的很差嗎? 那但是精心設計的啊。

    仔細思考了兩天,小李終於意識到了問題所在: 不是本身設計的很差, 是Java 語言太「低級」了 !

    自動化Build要描述的實際上是任務,是業務層面的東西。

    而用java 是個什麼都能幹的通用語言, 用它來寫確定引入了太多的細節,致使了閱讀和編寫的難度!

    小李想:能不能開發一套新的,專門爲自動化Build 所使用的語言呢?

    (碼農翻身注: 這其實就是所謂的領域特定語言(Domain Specific Language , 簡稱 DSL ))

    可是開發一套新語言那成本可就有點高了, 有點得不償失。

    小李百思不得其解, 直到有一天聽到小梁和項目經理在討論hibernate 的配置文件,忽然想到 像spring , hibernate 都是用XML來描述系統的。

    「那個人BuildTool也徹底能夠用XML來描述啊」小李趕忙把那個編譯java 的程序用XML描述了一下:

    小李的 Build 之路 (上)_Java

    果真是清爽多了! 和原來的Java程序比起來, 這段XML幾乎就是自解釋的 !

    XML可擴展性極強, 能夠任意自定義標籤諸如<javac> <srcDir> <classpath> 用它來描述Build的邏輯。

    可是惟一不爽的地方就是: XML 沒法像 Java程序那樣運行, 只是純文本而已。

    不過這也無妨,只要用Java寫一個解析器,用來解析這些XML文件而後在Java中執行就能夠了。有了BuildTool V1.0做爲基礎, 寫一個解析器不是什麼難事, 很快 BuildTool V2.0 就新鮮出爐了。

    小李再也不幫其餘項目組去寫Build 程序,由於用XML描述之後,你們很快就能學會, 而且樂在其中。

    CTO老張看到這個工具,大爲讚揚, 它給小李說: 「別叫什麼Build Tool, 太俗, 別人聽了一點感受都沒有, 我給你起個名,叫 ANT 」

    "ANT? " 小李彷佛看到不少小螞蟻在不辭勞苦幫着作Build, 內心暗暗佩服老張: 這個名字起的太好了, 姜仍是老的辣啊。

小李的Build之路(下)

轉自: 劉欣 碼農翻身 2016-07-12

前言: 接上一篇《小李的Build之路(上)

小李發明的ANT確實是好用, 如今不只僅是小李的公司, 連其餘公司的朋友據說了,也拿去使用, 交口稱讚。

只是小李發現了一點奇怪的現象,每一個人在開始寫新項目的Ant build文件以前, 都會找到本身說:

「小李, 把你那個build.xml 文件發我一份吧, 讓我參考下。」

小李的那一份build.xml實際上是本身項目的第一個ant 腳本, 爲啥你們都要把它

Copy走呢?   剛開始的時候小李覺得你們不會寫,要按照本身的模板照葫蘆畫瓢。 

偶然有一次,小李看到了別人項目的Ant build腳本, 不禁得大吃一驚, 這簡直和本身原始的build.xml一模一樣。 

小李趕忙把公司內全部項目的Ant腳本都要過來,仔細觀察了一下, 很快就發現了這些腳本中蘊藏着一些共同的「模式」,這些模式主要體如今Build的步驟上:

1. 從版本控制系統下載代碼

2. 編譯java 文件,造成jar包

3. 運行單元測試

4. 生成代碼覆蓋度報告和測試報告

4. 打包造成war 文件

5. 上傳到測試服務器上,進行安裝

其實這也難怪,實際的Build不就是這樣的嘛。 可是中間也有不一樣之處:

(1) 路徑不一樣,例如

java 源文件 下載下來之後放的位置不一樣,五花八門

編譯成的java class 放置的位置不一樣

測試報告放置不一樣

war包生成後放置的路徑不一樣

。。。

(2)  項目依賴不一樣,例如

各個項目依賴的第三方jar包多是不同的

各個項目都有一個Web子項目,它依賴於其餘java 項目,因此在build的時候,要先build這些java 項目才行

例以下圖中的OnlineShop,這是個Web項目, 它依賴於ApplicationConfg, LoggingFramework, OnlineShopApi這三個子項目。

項目依賴這個沒辦法, 畢竟是各個項目的業務所要求的,小李沒有辦法改變。

可是那些不一樣的路徑真的是必要的嗎?   能不能讓你們的路徑都保持一致呢 ? 

一個新的主意像閃電同樣劃過黑暗的夜空: 

確實能夠保持一致, 可是你們都要遵循必定的約定

若是你們都這麼作,小李就能夠加強一下Ant,只要運行ant  complie , 就會自動的去src/main/java 找到源文件進行編譯, 只要運行ant test,        就會自動去src/test/java 找到測試用例, 編譯並運行。

換句話說,只要遵循目錄的約定, 你們就不用費心費力的指定各類路徑了, 一切在背後由工具自動搞定, 這樣的話Build腳本就能夠極大的簡化了,只須要寥寥幾行便可。

這只是一個java項目,要是多個java項目,有依賴關係,像上面提到的 OnlineShop 依賴OnlineShopAPI, AppplicationConfig, LoggingFramework , 該怎麼處理?

這也不難, 小李想,首先每一個java項目都得遵照上述約定,其次須要定義項目之間的依賴關係, 也能夠用XML描述出來。

每一個java項目都須要有個叫pom.xml的文件, 例如OnlineShop這個項目的pom以下:

這樣以來工具就能自動找到被依賴的項目, 而後去編譯打包它了。

此外,各個java項目之間也須要按約定來組織目錄,例如:

+- pom.xml

+- online-shop-web

| +- pom.xml

| +- src

|   +- main

|     +- webapp

+- online-shop-api

| +- pom.xml

| +- src

|   +- main

|     +- java

+- logging-framework

| +- pom.xml

| +- src

|   +- main

|     +- java

+- app-config

| +- pom.xml

| +- src

|   +- main

|     +- java

若是擴展一下, 把第三方的jar 文件例如JUnit 也能夠給用這種方式來描述:

想到這一層,小李不由激動起來,由於第三方的jar 管理一直是一個使人頭疼的問題,最先的時候你們都是手工的Copy來Copy去, 因爲版本不一樣致使的錯誤特別難於發現。

每一個人在創建本身Eclipse workspace的時候, 得拿到全部依賴的jar包, 而且在項目上設置好, 但是很是的費勁啊。 

若是利用這種聲明的辦法, 每一個人豈不卸下了一個巨大的包袱 ? 

固然公司須要創建一個公用的第三方jar 文件版本庫, 把公司最經常使用的第三方jar包都放進去, 工具在分析項目的配置文件pom.xml的時候,就能夠去公司的版本庫裏去讀取而且下載到本地。

未來有新人進入公司, 只要給他一個pom.xml , 用Eclipse導入,就能輕鬆的把一個能夠直接運行的workspace創建起來, 不再須要設置那些煩心的jar了。

若是未來在網絡上創建公開的軟件版本庫, 任何人均可以從那裏去下載各類軟件包,那受惠的可不只僅是本身公司了, 而是全部人,真是一個激動人心的場景啊。

不過仍是從本身公司開始吧, 小李冷靜下來分析了一下: 讓全部的項目組都使用約定的目錄,而且創建一個公司級別的軟件庫,本身但是沒有這樣的權限啊, 小李去找CTO老張求助。

老張不愧是老江湖, 聽了幾分鐘小李的介紹,立刻就明白了, 而且把這個想法提高了一個高度:

「你這叫約定重於配置, 知道不?  從Ruby on Rails 開始,這個詞開始流行了, 你們如今都很忙, Ant build腳本用的也沒問題,先不改了」

小李還不死心: 「但是這麼作的話對之後的新項目大有好處啊,不用Copy 繁瑣的build腳本了, 也不用費心的折騰workspace了」

「那也不能如今改,項目進度最重要,你們都沒時間, 這樣吧,等你們項目閒下來再改動如何? 」 老張妥協了一下。

但是在公司基本上就不會有空閒的時間, 一個個新需求壓的你們透不過氣來,偶爾有空閒時間,你們也都犯懶了, 老是想休息。 

此外慣性的力量是驚人的,你們都願意待在溫馨區裏, 不肯意變化,  雖然也看到了新工具的好處, 你們都懶得換新的。 

時間過的很快,一年過去了, 小李看着本身辛辛苦苦加班寫出來的Ant 2.0 ,  仍是無人採用, 非常傷心。 

通過公司的容許, 小李決定把這個工具開源, 爲了和Ant區分開來, 特意起了個新的名稱: Maven。

Maven 迅速被你們用了起來,除了小李的公司。

又過了半年, 小李跳槽了。 

(完)

(完)

Maven 三十分鐘入門

閱讀 1164

收藏 95

2017-05-08

原文連接:sadwxqezc.github.io

騰訊雲移動開發者專區,一站式涵蓋開發,測試,發佈,營銷、運維等全生命週期,有效下降技術門檻、減小研發成本、提高效率。當即瞭解詳情:cloud.tencent.com

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.

參考文檔:Maven Documentation

Maven概述

一個基本的Pom文件

<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.mycompany.app</groupId>
  my-app
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>Maven Quick Start Archetype</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      junit
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Pom文件是面向工程的一個管理模型,全稱是Project Object Model。這個Pom文件中包含的基本內容有:

  1. project pom文件的頂層元素
  2. modelVersion Pom對象模型的版本
  3. groupId 是建立這個項目的組織或部門的惟一標誌,好比說org.apache.maven.plugins就是全部Maven plugins的groupId
  4. artifactId 是這個項目生成結果的惟一標誌,Maven生成結果的命名模式爲-<version>.<extension>,好比說my app-1.0.jar
  5. packaging 這個參數代表了項目生成結果的打包模式,好比JAR,WAR,EAR等,同時這個參數還代表了build過程採用的特定生命週期
  6. version 這個參數代表了項目生成結果的版本,在version裏常常會看到SNAPSHOT標誌,它代表了項目處於開發階段。
  7. name 這個參數表明項目的展現名字,一般做用在Maven生成的文檔中
  8. url 這個參數表明哪裏能夠找到該項目,一般做用在Maven生成的文檔中
  9. description 這個參數描述了項目的基本信息,一般做用在Maven生成的文檔中

Maven項目的基本結構

my-app
|-- pom.xml
`-- src
    |-- main
    |   `-- java
    |       `-- com
    |           `-- mycompany
    |               `-- app
    |                   `-- App.java
    `-- test
        `-- java
            `-- com
                `-- mycompany
                    `-- app
                        `-- AppTest.java

上面是一個Maven項目的基本結構,項目的相關資源位於${basedir}/src/main/java中,而測試的資源位於${basedir}/src/test/java中,而pom文件位於pom.xml中。

Maven的執行

1. mvn compile

執行mvn compile,編譯的結果會默認放在${basedir}/target/classes目錄下。

2. mvn test

執行mvn test,會執行${basedir}/src/test/java中的單元測試。若是隻想編譯測試代碼而不執行,則執行mvn test-compile

3. mvn package

執行mvn package會對項目進行打包,假如當前在pom中的packaging設定爲jar,那麼執行該命令後會在${basedir}/target目錄下生成對應的jar包。

4. mvn install

若是想把mvn package生成的Jar文件安裝在本地庫中以讓其它項目引用,則能夠執行mvn install命令,將生成的jar包放在${user.home}/.m2/repository中。

Plugins

Plugins用來定製Maven項目的編譯過程,假如要配置Java Compiler容許JDK 5.0的資源,那麼只須要在Pom中增長以下內容:

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      maven-compiler-plugin
      <version>3.3</version>
      <configuration>
        <source>1.5</source>
        <target>1.5</target>
      </configuration>
    </plugin>
  </plugins>
</build>

<configuration>中的配置會應用在對應Plugin的全部Goal。

資源文件打包

${basedir}/src/main/resources目錄下的全部文件都會被打包到Jar文件中,好比以下一個文件結構:

my-app
|-- pom.xml
`-- src
    |-- main
    |   |-- java
    |   |   `-- com
    |   |       `-- mycompany
    |   |           `-- app
    |   |               `-- App.java
    |   `-- resources
    |       `-- META-INF
    |           `-- application.properties
    `-- test
        `-- java
            `-- com
                `-- mycompany
                    `-- app
                        `-- AppTest.java

該項目打包成Jar文件後的內部組織結構爲:

|-- META-INF
|   |-- MANIFEST.MF
|   |-- application.properties
|   `-- maven
|       `-- com.mycompany.app
|           `-- my-app
|               |-- pom.properties
|               `-- pom.xml
`-- com
    `-- mycompany
        `-- app
            `-- App.class

文件過濾

Maven支持文件過濾的功能,能夠在build時候爲文件提供變量賦值,好比說上面的application.properties文件中有以下定義:

# application.properties
application.name=${project.name}
application.version=${project.version}

那麼須要在pom文件中作以下的定義:

<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.mycompany.app</groupId>
  my-app
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>Maven Quick Start Archetype</name>
  <url>http://maven.apache.org</url>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      junit
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <resources>
      <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
      </resource>
    </resources>
  </build>
</project>

執行mvn process-resources命令後,在target/classes下找到application.properties能夠看到以下結果:

# application.properties
application.name=Maven Quick Start Archetype
application.version=1.0-SNAPSHOT

可見其中形如${<property name>}的變量已經被替換成了對應的值,若是要引入其它文件中定義的屬性,只須要在pom文件中定義<filters>,好比:

<build>
    <filters>
      <filter>src/main/filters/filter.properties</filter>
    </filters>
    <resources>
      <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
      </resource>
    </resources>
  </build>

那麼Maven會先讀出filter.properties中的屬性,而後把這些屬性注入對應的resources中。

Dependencies

<dependencies>標籤下列出了全部的外部依賴,好比下面的Pom文件添加了Junit的依賴:

<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.mycompany.app</groupId>
  my-app
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>Maven Quick Start Archetype</name>
  <url>http://maven.apache.org</url>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      junit
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

<dependency><scope>標籤的值能夠爲compile,test和runtime,當Maven編譯項目時,它首先會在${user.home}/.m2/repository這個本地庫目錄下尋找所需的依賴,若是沒有會去遠程的庫上尋找,並將其下載到本地庫中,默認的遠程庫地址爲 http://repo.maven.apache.org/maven2/

包的發佈

當須要發佈一個包的遠程倉庫時,須要配置庫的地址和相應的權限,一個範例以下:

<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.mycompany.app</groupId>
  my-app
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>Maven Quick Start Archetype</name>
  <url>http://maven.apache.org</url>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      junit
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.codehaus.plexus</groupId>
      plexus-utils
      <version>1.0.4</version>
    </dependency>
  </dependencies>

  <build>
    <filters>
      <filter>src/main/filters/filters.properties</filter>
    </filters>
    <resources>
      <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
      </resource>
    </resources>
  </build>
  <!--
   |
   |
   |
   -->
  <distributionManagement>
    <repository>
      <id>mycompany-repository</id>
      <name>MyCompany Repository</name>
      <url>scp://repository.mycompany.com/repository/maven2</url>
    </repository>
  </distributionManagement>
</project>

它所須要的權限配置在settings.xml中:

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                      http://maven.apache.org/xsd/settings-1.0.0.xsd">
  ...
  <servers>
    <server>
      <id>mycompany-repository</id>
      <username>jvanzyl</username>
      <!-- Default value is ~/.ssh/id_dsa -->
      <privateKey>/path/to/identity</privateKey> (default is ~/.ssh/id_dsa)
      <passphrase>my_key_passphrase</passphrase>
    </server>
  </servers>
  ...
</settings>

多Modules管理

Maven很好的支持了多個Modules的管理,假如一個Maven項目結構以下:

+- pom.xml
+- my-app
| +- pom.xml
| +- src
|   +- main
|     +- java
+- my-webapp
| +- pom.xml
| +- src
|   +- main
|     +- webapp

對於根目錄下的pom文件,內容以下:

<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.mycompany.app</groupId>
  app
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>

  <modules>
    <module>my-app</module>
    <module>my-webapp</module>
  </modules>
</project>

其中的<modules>定義了其管理的兩個子modules。

假如my-webapp須要依賴my-app包,那麼在my-webapp/pom.xml中增長:

...
  <dependencies>
    <dependency>
      <groupId>com.mycompany.app</groupId>
      my-app
      <version>1.0-SNAPSHOT</version>
    </dependency>
    ...
  </dependencies>

而後在my-app和my-webapp的pom文件中都增長parent配置:

<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">
  <parent>
    <groupId>com.mycompany.app</groupId>
    app
    <version>1.0-SNAPSHOT</version>
  </parent>
  ...

而後在最頂層目錄下執行mvn clean install,會建立my-webapp/target/my-webapp.war,其中包含:

$ jar tvf my-webapp/target/my-webapp-1.0-SNAPSHOT.war
   0 Fri Jun 24 10:59:56 EST 2005 META-INF/
 222 Fri Jun 24 10:59:54 EST 2005 META-INF/MANIFEST.MF
   0 Fri Jun 24 10:59:56 EST 2005 META-INF/maven/
   0 Fri Jun 24 10:59:56 EST 2005 META-INF/maven/com.mycompany.app/
   0 Fri Jun 24 10:59:56 EST 2005 META-INF/maven/com.mycompany.app/my-webapp/
3239 Fri Jun 24 10:59:56 EST 2005 META-INF/maven/com.mycompany.app/my-webapp/pom.xml
   0 Fri Jun 24 10:59:56 EST 2005 WEB-INF/
 215 Fri Jun 24 10:59:56 EST 2005 WEB-INF/web.xml
 123 Fri Jun 24 10:59:56 EST 2005 META-INF/maven/com.mycompany.app/my-webapp/pom.properties
  52 Fri Jun 24 10:59:56 EST 2005 index.jsp
   0 Fri Jun 24 10:59:56 EST 2005 WEB-INF/lib/
2713 Fri Jun 24 10:59:56 EST 2005 WEB-INF/lib/my-app-1.0-SNAPSHOT.jar

可見my-app-1.0-SNAPSHOT.jar已經被放到了WEB-INF/lib目錄下。

微信公衆號【黃小斜】大廠程序員,互聯網行業新知,終身學習踐行者。關注後回覆「Java」、「Python」、「C++」、「大數據」、「機器學習」、「算法」、「AI」、「Android」、「前端」、「iOS」、「考研」、「BAT」、「校招」、「筆試」、「面試」、「面經」、「計算機基礎」、「LeetCode」 等關鍵字能夠獲取對應的免費學習資料。

                     

相關文章
相關標籤/搜索