1. 程式人生 > >maven多個web模組進行合併

maven多個web模組進行合併

 在一個大專案中拆分maven工程時,通常會根據業務模組進行拆分。無論怎麼劃分,往往每個模組又需要整合許可權管理orm或者說依賴 靜態資源web公共模組。而為了避免資源的浪費,或者是希望一次登入,可以訪問多個模組, 也就是希望合併多個web打包部署。 
   
 實際當中,在開發的時候,為了方便,開發人員希望每個業務模組都可單獨部署。而釋出的時候,釋出人員希望合併部署。 
   
 因此,在實際應用中,我們需要考慮如下問題:

  • 1、war專案C和war專案B都依賴war專案A和JAR專案X. 專案A中儲存了B和C專案通用的web資源,比如通用的javascript,CSS,jsp等.專案X中儲存了B和C專案中都依賴的一些class
  • 2、開發人員希望每次都只面對一個專案,即Team A 開發專案A, Team B開發專案B, Team C開發專案C….以此類推
  • 3、每個Team在開發自己專案時,都希望能直接進行除錯,例如war專案A可以直接部署到TOMCAT上執行測試
  • 4、實際交付給客戶的卻只有2個專案: B和C .也就是說,最後要打包B和C,而在B和C的war包中都要包含A中的web資源和X中的class
  • 5、最後如果war專案A是一個載入公共快取資源, 而且希望可以手動更新快取, 並同時對war專案C和war專案B產生作用,而B和C是希望通過class去呼叫,而不是希望通過寫一個a的介面去呼叫。

     如何解決上訴問題? 
       
     首先看一下web工程test部署後的目錄檢視: 
      test (webapp) 
         - - META-INF 
          - - MANIFEST.MF 
        - - WEB-INF 
          - - classes (src/main/

    Java編譯後的類) 
          - - lib (第三方架包) 
          - - web.xml 
          - - … (src/main/resources下的配置檔案) 
        - - … (webapp目錄下的其他的靜態資源)

     假如有兩個web, test1和test2,如果手動操作合併打包,我們需要按照一下介個步驟。 
     1、 先建立一個test.war, 
     2、 將test1和test2的.class檔案打包到 test/WEB-INF/classes目錄 
     3、 將test1和test2的lib檔案打包到 test/WEB-INF/lib目錄下 
     4.、將test1和test2的web.xml檔案內容合併,並且放到 test/WEB-INF/目錄下 
     5、 將test1和test2的src/main/resources下的配置檔案,複製到 test/WEB-INF/目錄下, 如果存在同名檔案,要麼合併,要麼改名 
     6、 將test1和test2的webapp的目錄靜態資源,複製到 test/WEB-INF/目錄下。 
      
     從上訴步驟來看,我們需要注意下面三個事情: 
     1、web.xml配置檔案在合併打包的時候,需要將其內容合併,相對麻煩 
     2、 src/main/resources下的配置檔案, 同名配置檔案內容不同時,需要保證名字不一樣或者將配置內容合併, 容易出錯 
     3、同樣,webapp的目錄靜態資源,同名配置檔案內容不同時,也需要保證名字不一樣,無法合併,很容易出錯

     因此在開發各模組的時候,我們需要做到: 
     1、各模組之間儘可能的保證不存在同名檔案 
     2、不能不存在的同名檔案,如web.xml,儘可能保證內容一致。或者建立一個父工程,把所有模組之間的web.xml融合進去。如spring-mvc.xml,儘可能把相同的配置放在父工程。然後把特性的配置放在特有的模組之中,如bean.xml配置檔案,注意保證該bean.xml不存在重複的。

     那麼在maven中是怎樣合併打包部署呢?沒錯,就是使用overlays。overlays就是將上述所說的操作步驟自動化了。在overlay標籤中,可以過濾到重複的配置檔案等等。 
      
     我們看一下在父工程test中怎樣配置,使得能合併打包test1和test2。使用overlay標籤,也得注意我們上面所說的注意事項。避免同名重複配置檔案等導致部署失敗。

     好了,廢話不多說,直接上配置檔案程式碼吧。 
      
     pom.xml

    <dependencies>
        <!-- 如果test的中有對test1和test2的依賴,這個配置是不可少的-->
        <dependency>
            <groupId>cn.com.xlxxcc</groupId>
            <artifactId>test1</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>cn.com.xlxxcc</groupId>
            <artifactId>test2</artifactId>
            <version>1.0.0</version>
        </dependency>

        <!-- 下面的這個配置,在整合其他war的時候,是必不可少的 -->
        <dependency>
            <groupId>cn.com.xlxxcc</groupId>
            <artifactId>test1</artifactId>
            <version>1.0.0</version>
            <type>war</type>
        </dependency>
        <dependency>
            <groupId>cn.com.xlxxcc</groupId>
            <artifactId>test2</artifactId>
            <version>1.0.0</version>
            <type>war</type>
        </dependency>
    </dependencies>

    <build>
        <finalName>test</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <packagingExcludes>WEB-INF/web.xml</packagingExcludes>
                    <overlays>
                        <!-- 合併test1 -->
                        <overlay>
                            <groupId>cn.com.xlxxc</groupId>
                            <artifactId>test1</artifactId>
                            <!-- 過濾test1中相同的配置檔案 -->
                            <excludes>
                                <exclude>**/*-context.xml</exclude>
                                <exclude>**/*-ds.xml</exclude>
                            </excludes>
                        </overlay>
                        <!-- 合併test2 -->
                        <overlay>
                            <groupId>cn.com.xlxxcc</groupId>
                            <artifactId>test2</artifactId>
                            <!-- 過濾test2中相同的配置檔案 -->
                            <excludes>
                                <exclude>**/*-context.xml</exclude>
                                <exclude>**/*-ds.xml</exclude>
                            </excludes>
                        </overlay>
                    </overlays>
                </configuration>
            </plugin>
        </plugins>
    </build>

  至於overlay標籤的配置詳解,大家可以查一下api.

    這篇文章,我準備分3個部分來介紹:

  1. maven多模組專案。
  2. maven多web合併專案。
  3. maven多web合併專案在eclipse+tomcat環境下部署和除錯。

      maven多模組專案

        maven多模組專案需要一個父工程來聚合各個子模組,不過其實就是需要一個父pom.xml,主要作用是宣告子模組,程式碼如下:

<modules>
	<module>modules/fixflow-core</module>
	<module>modules/fixflow-expand</module>
	<module>modules/fixflow-common-api</module>
	<module>modules/fixflow-common-servlet</module>
	<module>modules/fixflow-manage-servlet</module>
	<module>modules/fixflow-webapp-common</module>
	<module>modules/fixflow-webapp-taskcenter</module>
	<module>modules/fixflow-webapp-managecenter</module>
	<module>modules/fixflow-webapp-explorer</module>
	<module>modules/fixflow-converter</module>
	<module>modules/fixflow-webapp-editor</module>
</modules>

      然後在子模組中,宣告父工程,子模組中程式碼如下:

<parent>
    <groupId>com.founder.fix.fixflow</groupId>
    <artifactId>fixflow-root</artifactId>
    <version>5.0</version>
    <relativePath>../..</relativePath>
</parent>

       關於多模組的文章,網上有很多,也都很詳細,這裡不再多說。

       maven多web合併專案

        多web專案合併,主要是我在網上找到的資料都不是我最終想要的效果,所以這裡就介紹下我最終使用的方案,網上有很多方案都是介紹用caro外掛,我到現在也不明白為什麼要使用這個外掛。

        maven的多web模組maven-war-plugin外掛的overlays屬性來處理,最終主web專案pom.xml程式碼如下

<build>  
		<finalName>bpmcenter</finalName>  
		<plugins>  
			<!-- 合併多個war -->  
			<plugin>  
				<groupId>org.apache.maven.plugins</groupId>  
				<artifactId>maven-war-plugin</artifactId>  
				<configuration>  
					<packagingExcludes>WEB-INF/web.xml</packagingExcludes>	
					<overlays>  
						<overlay>  
							<groupId>com.founder.fix.fixflow</groupId>  
							<artifactId>fixflow-webapp-taskcenter</artifactId>  
						</overlay>   
					</overlays>  
				</configuration>  
			</plugin>  
		</plugins> 
</build>

    這裡使用到了maven-war-plugin,用overlay屬性已經足夠將多web合併了,只是用的過程中需要注意以下幾點:

  1. 被合併的子web專案packaging屬性必須是war
  2. 被合併的子web專案,必須在主專案中新增依賴關係。
  3. 被合併的子web專案中,如果沒有web.xml,則需要在pom.xml中宣告
    <build>
    	<finalName>fixflow-webapp-editor</finalName>
    		<plugins>  
    			<plugin>  
    				<groupId>org.apache.maven.plugins</groupId>  
    				<artifactId>maven-war-plugin</artifactId>  
    				<configuration>  
    					<failOnMissingWebXml>false</failOnMissingWebXml>  
    				</configuration>  
    			</plugin>	 
    		</plugins>  
    </build>

        做完以上幾點,多web專案合併就基本上做完了,執行mvn install就會發現打出的war包中已經存在了其他子模組的專案。

       多web專案在eclipse+tomcat環境下部署除錯

        在eclipse裡面使用,其實更簡單,只是網上的說法太複雜了而已,對於習慣了tomcat開發的使用者來說。

        對於maven專案,一個環境到另一個環境應該只有pom.xml檔案和src資料夾就夠了,其他都是使用者根據自己的環境來做的。

  1. 開啟eclipse,修改本地maven倉庫地址,匯入maven專案,等待構建結束。
  2. 建立server,開啟window-prefrences-server-runTime Environment-new ....選擇tomcat路徑,jdk資訊,這一步和原來完全一樣。
  3. 開啟server檢視,new server,這裡選中剛才建立的tomcat,點選next,這步只需要主web專案新增進來即可。
  4. 雙擊建立的server,選擇將專案釋出到tomcat的webapps目錄下,點選pushlish,完成。

       再去tomcat目錄,發現已經將合併後的web釋出到對應目錄下了。 引用的其他Java專案已經被打包成jar釋出到lib下了,不過你可以打個斷點試試,依然可以除錯,修改一段程式碼,發現熱部署也是可以的,這樣就和原來的開發習慣完全一樣了。