Maven工程war包依賴基礎(chǔ)war包的解決方案及坑點

一、業(yè)務(wù)場景

傳統(tǒng)的SSM項目一般都為war包部署,多模塊的項目一般都是將模塊打包成jar包依賴進web工程中,但是對于作為基礎(chǔ)項目或者分模塊的web項目來說,打成war包對靜態(tài)資源的訪問就不太方便;這里介紹一下通過Maven WAR Plugin的<overlays>解決這個問題。這對于沒有上微服務(wù)的項目來說應(yīng)該是個不錯的解決方案,將通用的常規(guī)化的功能抽到base.war中,而其他類似項目依賴base.war作為基礎(chǔ)項目的一個模塊并對其做小部分定制化的修改即可,大大提高了同類型項目的交付周期。

二、overlay簡介

Overlays(覆蓋)主要用于跨多Web項目間共享公共資源。它能夠在目標(biāo)WAR本身覆蓋除了原生WAR構(gòu)件以外的所有文件,并在WEB-INF/lib目錄下收集原生WAR項目的依賴。

<overlay>元素包含有下列子元素:
id - overlay id。如果你不提供的話,WAR插件將自動生成一個。
groupId - 配置你想要覆蓋的groupId。
artifactId – 配置你想要覆蓋的構(gòu)件的artifactId。
type – 配置你想要覆蓋的構(gòu)件類型。默認值是:war。
classifier – 如果有多個構(gòu)件匹配當(dāng)前的groupId/artifactId,那么你需要配置構(gòu)件的classifier以明確覆蓋(classifier:該元素用來幫助定義構(gòu)建輸出的一些附屬構(gòu)件)。
includes - 要包含的文件。默認情況下,所有文件都能被包含。
excludes – 要排除的文件。默認情況下,在META – INF目錄是被排除在外的。
targetPath - 在webapp結(jié)構(gòu)的目標(biāo)相對路徑,當(dāng)然這只在覆蓋類型為war時才有效。默認情況下,覆蓋的內(nèi)容都追加在webapp的根節(jié)點下。
skip – 當(dāng)設(shè)置為true時,跳過本次覆蓋。默認值是:false。

三、實現(xiàn)方式

基礎(chǔ)項目:base.war,具體開發(fā)項目:a.war
如果在a項目中沒有對base項目種具體方法的引用,則只需要在a項目中添加下面的build節(jié)點。

<build>
    <finalName>a</finalName>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>3.0.0</version>
            <configuration>
                <overlays>
                    <overlay>
                        <groupId>ff</groupId>
                        <artifactId>base</artifactId>
                    </overlay>
                </overlays>
            </configuration>
        </plugin>
    </plugins>
</build>

這樣便可以實現(xiàn)將base項目中同包同名的文件進行覆蓋,但是這也僅僅局限于靜態(tài)資源,如果我們需要引用Java的某各類,那么在打包的時候會發(fā)現(xiàn)出現(xiàn)找不到j(luò)ava類的報錯。
問題原因:
由于開發(fā)中我們只需要覆蓋部分文件,方法調(diào)用依然是調(diào)用base中定義的方法,但根據(jù)Java規(guī)范,classpath不能指定WAR文件。這就意味著在開發(fā)工具中調(diào)試時,項目可以正常運行;但是在編譯時,a項目無法訪問base項目中定義的類,所以在a項目中,我們不能像常規(guī)類組件那樣擴展或使用base定義的類。要解決這一問題,我們必須在base中重新設(shè)置maven-war-plugin的一項缺省配置,將classes打包成jar包引入到a中,這樣才能使得a編譯打包成功。相關(guān)pom配置。
在base項目中添加maven-war-plugin插件:

<build>
    <finalName>base</finalName>
    <plugins>
        <plugin>
            <artifactId>maven-war-plugin</artifactId>
            <configuration>
                <!-- 把class打包jar作為附件 -->
                <attachClasses>true</attachClasses>
            </configuration>
        </plugin>
</plugins>
</build>

在a項目中引入上面打包的jar文件:

<dependencies>
    <dependency>
        <groupId>ff</groupId>
        <artifactId>base</artifactId>
        <version>1.0.0</version>
        <type>jar</type>
        <classifier>classes</classifier>
        <scope>provided</scope>
    </dependency>
</dependencies>

這里還要注意下scope不能隨意修改,這個jar我們只是編譯需要,不需要放到最終打包的war文件中,如果放入最終的war包中,啟動時Mybatis會報錯(具體原因是Mapper文件的namespace重名了,因為項目中有一份,jar包中還有一份)。

<scope>可以使用5個值:

  • compile,缺省值,適用于所有階段,會隨著項目一起發(fā)布。
  • provided,類似compile,期望JDK、容器或使用者會提供這個依賴。如servlet.jar。
  • runtime,只在運行時使用,如JDBC驅(qū)動,適用運行和測試階段。
  • test,只在測試時使用,用于編譯和運行測試代碼。不會隨項目發(fā)布。
  • system,類似provided,需要顯式提供包含依賴的jar,Maven不會在Repository中查找它。

依賴范圍控制哪些依賴在哪些classpath 中可用,哪些依賴包含在一個應(yīng)用中。讓我們詳細看一下每一種范圍:

compile (編譯范圍)

compile是默認的范圍;如果沒有提供一個范圍,那該依賴的范圍就是編譯范圍。編譯范圍依賴在所有的classpath 中可用,同時它們也會被打包。

provided (已提供范圍)

provided 依賴只有在當(dāng)JDK 或者一個容器已提供該依賴之后才使用。例如, 如果你開發(fā)了一個web 應(yīng)用,你可能在編譯 classpath 中需要可用的Servlet API 來編譯一個servlet,但是你不會想要在打包好的WAR 中包含這個Servlet API;這個Servlet API JAR 由你的應(yīng)用服務(wù)器或者servlet 容器提供。已提供范圍的依賴在編譯classpath (不是運行時)可用。它們不是傳遞性的,也不會被打包。

runtime (運行時范圍)

runtime 依賴在運行和測試系統(tǒng)的時候需要,但在編譯的時候不需要。比如,你可能在編譯的時候只需要JDBC API JAR,而只有在運行的時候才需要JDBC
驅(qū)動實現(xiàn)。

test (測試范圍)

test范圍依賴 在一般的編譯和運行時都不需要,它們只有在測試編譯和測試運行階段可用。

system (系統(tǒng)范圍)

system范圍依賴與provided 類似,但是你必須顯式的提供一個對于本地系統(tǒng)中JAR 文件的路徑。這么做是為了允許基于本地對象編譯,而這些對象是系統(tǒng)類庫的一部分。這樣的構(gòu)件應(yīng)該是一直可用的,Maven 也不會在倉庫中去尋找它。如果你將一個依賴范圍設(shè)置成系統(tǒng)范圍,你必須同時提供一個 systemPath 元素。注意該范圍是不推薦使用的(你應(yīng)該一直盡量去從公共或定制的 Maven 倉庫中引用依賴)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ANT build.xml文件詳解(一) Ant的概念 可能有些讀者并不連接什么是Ant以及入可使用它,但只要使用...
    SkTj閱讀 4,166評論 0 2
  • Maven的基本了解 什么是Maven? Maven就是Apache下的一個開源項目。它是用純java開發(fā)的。是一...
    Bcome閱讀 3,145評論 0 7
  • 一、maven的兩個作用 項目自動化構(gòu)建,通過命令行就可以完成整個項目構(gòu)建過程,不需要我們手動地進行項目構(gòu)建 管理...
    lifeline張閱讀 916評論 0 1
  • 1.編寫POM Maven項目的核心文件是pom.xml,POM(Project Objcet Model)項目對...
    zlcook閱讀 6,008評論 7 26
  • 總結(jié):在周線上面,本周滬指收獲一根周漲幅1.88%、近乎光頭光腳的(周)小陽線。下方,3200點,即10周線一帶,...
    zzh0186閱讀 250評論 0 0

友情鏈接更多精彩內(nèi)容