模塊化管理(二)

這一章我們介紹的是,Overlay的使用,通過將多個war包最終打成一個war包。

一、工程介紹 


該項目由5個maven項目組成 

 

task-aggregator是父工程,同時承擔聚合模塊和父模塊的作用,沒有實際代碼和資源文件 
task-common是基礎工程,裏面是公共的代碼 
task-sla是某一個業務子模塊,不包含web內容 
task-sla-web是某一個web子模塊 
task-web-dist是最外圍的web工程,聚合多個web工程,形成最終的war包 

依賴關係是:task-common <-- task-sla <-- task-sla-web <-- task-web-dist 

二、task-aggregator 

 

這個工程是起到聚合作用,並充當parent pom,所以沒有任何實際代碼和資源文件。我這裏選擇了平行結構,另外一種方式是樹形結構,我個人感覺平行結構看起來更舒服一點 

下面是pom,有所簡化: 
Xml代碼  收藏代碼
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  2.     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  3.   
  4.     <!-- 定義公共變量 -->  
  5.     <properties>  
  6.         <spring.version>3.1.0.RELEASE</spring.version>  
  7.         <struts2.version>2.3.1</struts2.version>  
  8.         <hibernate.version>3.2.7.ga</hibernate.version>  
  9.     </properties>  
  10.   
  11.     <modelVersion>4.0.0</modelVersion>  
  12.     <groupId>com.xxx.task</groupId>  
  13.     <artifactId>task-aggregator</artifactId>  
  14.     <version>0.0.1-SNAPSHOT</version>  
  15.     <packaging>pom</packaging>  
  16.   
  17.         <!-- 待聚合模塊 -->  
  18.     <modules>  
  19.         <module>../task-common</module>  
  20.         <module>../task-sla</module>  
  21.         <module>../task-sla-web</module>  
  22.         <module>../task-web-dist</module>  
  23.     </modules>  
  24.   
  25.     <!-- 配置部署的遠程倉庫 -->  
  26.     <distributionManagement>  
  27.         <snapshotRepository>  
  28.             <id>nexus-snapshots</id>  
  29.             <name>nexus distribution snapshot repository</name>  
  30.             <url>http://10.78.68.122:9090/nexus-2.1.1/content/repositories/snapshots/</url>  
  31.         </snapshotRepository>  
  32.     </distributionManagement>  
  33.   
  34.     <build>  
  35.   
  36.         <pluginManagement>  
  37.             <plugins>  
  38.   
  39.                 <plugin>  
  40.                     <groupId>org.apache.maven.plugins</groupId>  
  41.                     <artifactId>maven-resources-plugin</artifactId>  
  42.                     <version>2.6</version>  
  43.                     <configuration>  
  44.                         <encoding>UTF-8</encoding>  
  45.                     </configuration>  
  46.                 </plugin>  
  47.   
  48.                 <plugin>  
  49.                     <groupId>org.apache.maven.plugins</groupId>  
  50.                     <artifactId>maven-compiler-plugin</artifactId>  
  51.                     <version>2.5.1</version>  
  52.                     <configuration>  
  53.                         <encoding>UTF-8</encoding>  
  54.                     </configuration>  
  55.                 </plugin>  
  56.   
  57.             </plugins>  
  58.         </pluginManagement>  
  59.   
  60.     </build>  
  61.   
  62.     <dependencyManagement>  
  63.   
  64.         <dependencies>  
  65.   
  66.             <dependency>  
  67.                 <groupId>com.sun</groupId>  
  68.                 <artifactId>tools</artifactId>  
  69.                 <version>1.6.0</version>  
  70.                 <scope>system</scope>  
  71.                 <systemPath>${env.JAVA_HOME}/lib/tools.jar</systemPath>  
  72.             </dependency>  
  73.   
  74.         </dependencies>  
  75.   
  76.     </dependencyManagement>  
  77.   
  78. </project>  

基本上是一目瞭然,只是有幾點注意下: 

    1、這裏配置了<distributionManagement>,這樣子項目就不需要重複配置了 

    2、通過<pluginManagement>,對一些插件進行了公共的配置,這裏主要是爲了消除構建時的告警 

    3、配置tools,是因爲實際中發現,其他開發人員從svn上check out工程以後,有的人會報錯,找不到tools.jar,這樣配置以後就好了 

三、task-common 

該工程是公共工程,提供了項目中的公共代碼,這裏只包括了通用的DAO組件,作爲示例。 

該工程不依賴任何其他工程 

 

該工程裏有幾點要點: 

    1、在代碼內部用了Spring的註解 
Java代碼  收藏代碼
  1. public abstract class GenericDAO<T> implements IGenericDAO<T> {  
  2.   
  3.     private Class<T> entityClass;  
  4.   
  5.     public GenericDAO(Class<T> clazz) {  
  6.         this.entityClass = clazz;  
  7.     }  
  8.   
  9.     @Autowired  
  10.     private HibernateTemplate hibernateTemplate;  
  11.   
  12. }  

這裏用到了@Autowired註解,所以最終形成的war包,必須在spring配置文件中聲明HibernateTemplate類型的bean,否則會報錯 

我這裏用的maven環境是maven3.0.4,這個版本打出的jar包,帶有Directory Entries信息,所以spring的註解即使在jar包中也可生效,如果是比較老的版本,spring的註解在jar包中不好用,關於這個問題的詳細描述,見另外一篇博客:http://kyfxbl.iteye.com/blog/1675368 

    2、單元測試的寫法 
Java代碼  收藏代碼
  1. @RunWith(SpringJUnit4ClassRunner.class)  
  2. @ContextConfiguration(locations = "classpath:spring-test.xml")  
  3. @Transactional  
  4. public class GenericDAOTest {  
  5.   
  6.     @Autowired  
  7.     private IBookDAO bookDAO;  
  8.   
  9.     @Test  
  10.     public void testInsert() {  
  11.         Book book = new Book();  
  12.         book.setName("thinking in java");  
  13.         book.setIsbn("111");  
  14.         bookDAO.insert(book);  
  15.     }  
  16.   
  17. }  

這裏用到了幾個註解,@RunWith是爲了在spring容器環境下跑這個單元測試類,以支持依賴注入。@ContextConfiguration是聲明spring配置文件的位置。@Transactional註解之後,在單元測試方法中的事務會自動回滾,這個比較方便,這樣在前面執行的方法,不會對後面的方法造成影響 

這個單元測試類,可以直接在maven裏跑起來,讓我比較驚喜。之前這樣寫,在ant裏跑沒有成功,可能是我沒有找到合適的插件的原因 

    3、除了測試的java代碼之外,還有3個資源文件,都是放在src/test/resources下,這些資源文件只在test階段生效,package階段不會被打包,也就是專門供測試階段使用 

這個各有利弊,優點是測試的配置文件與開發的配置文件隔離,互不干擾。缺點是配置文件似乎缺少了集中放置的地點,這樣如果多個maven工程都需要跑單元測試,要共享測試用配置文件,比較麻煩一點 

不過從我個人來看,也算是利大於弊。只是在每個maven項目下,都需要獨立的測試相關資源文件,其實也有利於分別修改 

另外,可以看到這裏的hibernate映射文件,不是和model類放在一個package下,而是放在resources目錄下的,這樣做可以避免一些潛在的問題,也有利於後續的聚合 

    4、pom文件沒有什麼特別的,只是要引入<scope>爲test的junit和spring-test 

四、task-sla 

該工程依賴task-common(因爲用到了GenericDAO),是某一個業務模塊的邏輯部分,包含了數據庫訪問層和業務邏輯層,但是不包括web相關的部分 

 

這裏沒有什麼特別要注意的,目錄結構和task-common基本一樣。比較特別的是可以看到Maven Dependencies裏,有一個task-common工程,所以task-common裏的任何修改,都可以第一時間在這個工程裏體現出來,是比較方便的 

關於這個問題,見另外一篇博客:http://kyfxbl.iteye.com/blog/1679806 

另外就是前面說過的,hibernate的映射文件,應該放在src/main/resources下,而不是與Model類放在一起 

五、task-sla-web 

這個工程是上述task-sla工程的web層,依賴於task-sla,由於task-sla又依賴task-common,所以這個工程最終會同時依賴task-common和task-sla 

 

然後這個工程裏包含了web層的東西,包括Action類、jsp、圖片、struts2的配置文件等,這些東西放在web工程裏是最合適的 

 

這裏需要注意2點: 

    1、這個工程的packaging類型是war,而不是jar。但是最終它不會獨立打出war包來,其src/main/webapp裏的所有文件,都會被最外圍的task-web-dist工程聚合成一個總的war 

    2、這個工程的WEB-INF目錄下,沒有web.xml(有也沒用,最終會被覆蓋)。默認情況下,packaging類型爲war的項目,如果沒有web.xml,則構建會失敗,因此需要在pom裏做一個配置 

該項目的pom如下,省略了依賴部分: 
Xml代碼  收藏代碼
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  2.     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">  
  3.   
  4.     <parent>  
  5.         <groupId>com.xxx.task</groupId>  
  6.         <artifactId>task-aggregator</artifactId>  
  7.         <version>0.0.1-SNAPSHOT</version>  
  8.         <relativePath>../task-aggregator</relativePath>  
  9.     </parent>  
  10.   
  11.     <modelVersion>4.0.0</modelVersion>  
  12.     <artifactId>task-sla-web</artifactId>  
  13.     <packaging>war</packaging>  
  14.   
  15.     <build>  
  16.         <plugins>  
  17.             <plugin>  
  18.                 <groupId>org.apache.maven.plugins</groupId>  
  19.                 <artifactId>maven-war-plugin</artifactId>  
  20.                 <configuration>  
  21.                     <failOnMissingWebXml>false</failOnMissingWebXml>  
  22.                 </configuration>  
  23.             </plugin>  
  24.         </plugins>  
  25.     </build>  
  26.   
  27.     <!-- 配置依賴 -->  
  28.     <dependencies>  
  29.         <dependency>  
  30.             <groupId>org.springframework</groupId>  
  31.             <artifactId>spring-beans</artifactId>  
  32.         </dependency>  
  33.   
  34.     </dependencies>  
  35.   
  36. </project>  

上面的<failOnMissingWebXml>,就是配置缺少web.xml也不使構建失敗 

六、task-web-dist 

這個工程是最外圍的web工程,起到聚合的作用,即把所有的web項目,打成最終的war包。同時,在這個工程裏,放置裏公共的配置文件,比如struts.xml、ssoconfig.properties等 

 

這個工程的聚合意圖十分明顯,比如struts.xml 
Xml代碼  收藏代碼
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd">  
  3.   
  4. <struts>  
  5.   
  6.     <constant name="struts.objectFactory" value="spring" />  
  7.     <constant name="struts.ui.theme" value="simple" />  
  8.     <constant name="struts.i18n.encoding" value="UTF-8" />  
  9.     <constant name="struts.action.extension" value="action" />  
  10.     <constant name="struts.enable.DynamicMethodInvocation" value="false" />  
  11.     <constant name="struts.devMode" value="true" />  
  12.   
  13.     <include file="struts2/struts-sla.xml" />  
  14.   
  15. </struts>  

提供了項目通用的配置,並把各子項目的struts2配置文件聚合起來。war包中的web.xml也是在這裏提供的 

下面是該工程的pom,也省略了依賴的配置: 這塊得注意,如果沒有加依賴,只用overlay的配置,pom文件會報錯,找不到依賴關係。所以要在上面加上依賴配置:

  1. <dependency> <groupId>com.huawei.inoc.wfm.task</groupId>  
  2.                             <artifactId>task-sla-web</artifactId>  </dependency> 

有多個就加多個。

Xml代碼  收藏代碼
  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  2.     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">  
  3.   
  4.     <parent>  
  5.         <groupId>com.xxx.task</groupId>  
  6.         <artifactId>task-aggregator</artifactId>  
  7.         <version>0.0.1-SNAPSHOT</version>  
  8.         <relativePath>../task-aggregator</relativePath>  
  9.     </parent>  
  10.   
  11.     <modelVersion>4.0.0</modelVersion>  
  12.     <artifactId>task-web-dist</artifactId>  
  13.     <packaging>war</packaging>  
  14.   
  15.     <build>  
  16.   
  17.         <finalName>task</finalName>  
  18.   
  19.         <plugins>  
  20.   
  21.             <!-- 合併多個war -->  
  22.             <plugin>  
  23.                 <groupId>org.apache.maven.plugins</groupId>  
  24.                 <artifactId>maven-war-plugin</artifactId>  
  25.                 <configuration>  
  26.                     <packagingExcludes>WEB-INF/web.xml</packagingExcludes>    
  27.                     <overlays>  
  28.                         <overlay>  
  29.                             <groupId>com.huawei.inoc.wfm.task</groupId>  
  30.                             <artifactId>task-sla-web</artifactId>  
  31.                         </overlay>  
  32.                     </overlays>  
  33.                 </configuration>  
  34.             </plugin>  
  35.   
  36.             <!-- 利用cargo啓動容器 -->  
  37.             <plugin>  
  38.                 <groupId>org.codehaus.cargo</groupId>  
  39.                 <artifactId>cargo-maven2-plugin</artifactId>  
  40.                 <version>1.2.3</version>  
  41.                 <configuration>  
  42.                     <container>  
  43.                         <containerId>tomcat7x</containerId>  
  44.                         <home>D:\apache-tomcat-7.0.29</home>  
  45.                     </container>  
  46.                     <configuration>  
  47.                         <type>standalone</type>  
  48.                         <home>${project.build.directory}/tomcat7.0.29</home>  
  49.                         <properties>  
  50.                             <cargo.jvmargs>  
  51.                                 -Xdebug  
  52.                                 -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8787  
  53.                             </cargo.jvmargs>  
  54.                         </properties>  
  55.                     </configuration>  
  56.                 </configuration>  
  57.                 <executions>  
  58.                     <execution>  
  59.                         <id>cargo-run</id>  
  60.                         <phase>pre-integration-test</phase>  
  61.                         <goals>  
  62.                             <goal>run</goal>  
  63.                         </goals>  
  64.                     </execution>  
  65.                 </executions>  
  66.             </plugin>  
  67.   
  68.         </plugins>  
  69.   
  70.     </build>  
  71.   
  72. </project>  

這裏主要是對maven-war-plugin和cargo-maven2-plugin這2個插件進行了配置,以起到聚合war,以及通過cargo啓動容器的作用 

關於多war聚合,以及cargo,見另外2篇博客:http://kyfxbl.iteye.com/blog/1678121、http://kyfxbl.iteye.com/blog/1677608 

七、啓動構建 

在task-aggregator目錄下,執行mvn clean deploy或者mvn clean install,就可啓動整個構建過程,並將容器啓動起來,跑最終生成的war包 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章