一个多maven项目聚合的实例

本文介绍一个多maven项目的实例demo,展示了聚合、继承、工程依赖、单元测试、多war聚合、cargo发布等场景 

一、工程介绍 

该项目由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,也省略了依赖的配置: 
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包 

转载自http://kyfxbl.iteye.com/blog/1680045

1.[今日课程内容总览] Maven--***** 介绍 优点 用maven创建一个项目, 用maven创建一个ssm项目,每一层的代码分开,把一个项目拆解成多个项目 2.[今日包含笔记] maven介绍: Eclise: 缺点: Jar包: 版本管理,解决jar包冲突:删除老的jar包,保留新的jar包 不同的项目,jar包要复制一份;Users Library 羡慕yum的好处,安装软件,自动下载,自动验证,自动安装,自动测试;镜像网站 Jar包的依赖: 致命的缺点:现象: 每一个项目都有前台(广大网民)和后台(管理员看的),后台的功能远远的大于>前台的功能;迭代升级;每次升级都要重启tomcat;将tomcat做很多个备份(10个),为了nginx转发;前台:访问比较大,管理员访问量比较小; 问题: 每次升级,10个tomcat都升级一次 后台的升级频繁要比前台频繁;升级10次,9次改的是后台的代码,只有一次是前台的代码 解决方案: 是将前台(广大网民看的页面)的代码和后台(管理员)的代码要分开,将原来的一个项目分别放到两个web项目;一个web项目一个tomcat;好处:更新的时候如果更新后台(管理员),只需要重启后台的tomcat(服务); 折成两个项目以后的缺点:Service以下的代码重复; 将Service层以下的代码放到一个新创建的java项目中,在部署的时候将Service(java项目)打成一个jar包,分别放到两个web服务中;编译的时候让web项目依赖与Service(java项目)_source folder;配置麻烦,项目项目之间的依赖头脑得相当清晰 这个缺点Maven解决了; 请听今天的内容 拆分前:图一 拆分后是图二 3. 介绍 官网:http://maven.apache.org/download.cgi 目录介绍: Bin:二进制文件 Boot:引导,启动 Conf:配置文件 Lib:jar包 README.txt:读我 3.1.修改配置文件的内容 路径:%MAVEN_HOME%\conf\settings.xml 配置文件代码: d:/repo alimaven aliyun maven http://maven.aliyun.com/nexus/content/groups/public/ central 注意: 千万不要将文档中的setting的内容全部替换到maven中的内容,要对比着修改,保留原来的; 只修改本地仓库,和下载镜像(源) 3.2.Eclipse Maven的配置 每打开一个新的工作空间,要配置一下Maven,然后再写代码 3.3.创建Maven项目 右击创建一个maven project Packing:有三种: Jar:java项目, War:web项目 Pom:文件夹,jar和war文件,mavenProject:一个项目,可以放jar和war包,通过pom,一般新创建的maven Project是POM 3.4.创建一个Maven Model 最外面的项目MavenProject,其它的全部是Maven Model 3.4.1.创建JAR 目录介绍: Mvn-jar |-->Src:源码:java代码 |-->|-->main:代码:除测试以外的代码:junit |-->|-->main|-->java:代码 |-->|-->main|-->resources:配置文件 |-->|-->test:测试的代码,junit |-->|-->test|-->java:代码 |-->|-->test|-->resources:配置文件 |-->Target:编译后的文件 |-->|-->classes:代码编译后的class类 |-->|-->test-classes:测试类编译后的classes 3.4.2.创建WAR 目录介绍: Mvn-war |-->Src:源码:java代码 |-->|-->main:代码:除测试以外的代码:junit |-->|-->main|-->java:代码 |-->|-->main|-->resources:配置文件 |-->|-->main|-->webapp:webContent,一般放jsp,js,css |-->|-->test:测试的代码,junit |-->|-->test|-->java:代码 |-->|-->test|-->resources:配置文件 |-->Target:编译后的文件 |-->|-->classes:代码编译后的class类 |-->|-->test-classes:测试类编译后的classes |-->|-->m2e-wtp:编译后的web服务;war解压后的内容 创建war包以后报以下错误: 因为创建的web项目,webapps少了web-inf,web.xml 解决方案: 在项目上右击,Javaee Tools-->第二个选项 3.5.配置编译环境 将maven项目重新编译,在项目中右击,可以pom上右击,可以将pom(目录)下面的jar和war重新编译 如果出现以上情况,说明下载的jar包有问题,把这下面的文件删除,重新下载 每创建一个项目,都有pom.xml,所有的配置都在pom.xml中 网址:所有的groupId和artifactId到这个网站中找 http://mvnrepository.com/ Pom.xml:配置文件示例(含的编译环境) 4.0.0 com.bjsxt mvn 0.0.1-SNAPSHOT pom mvn mvn mvn-jar mvn-war org.apache.maven.plugins maven-surefire-plugin true org.apache.maven.plugins maven-compiler-plugin <!-- 3.6.1 --> 1.7 1.7 UTF-8 org.apache.maven.plugins maven-source-plugin true compile jar org.apache.maven.plugins maven-resources-plugin UTF-8 3.6.生命周期 Maven -build:javac;编译 Maven-install:java先编译,后运行 在项目的target中会生成jar包和war包, 在仓库中生成相应的目录,里面的放的是jar包和war包 Maven-clean:会把项目中的class文件和jar包war包删除 Maven-test:运行所的测试类,取决于位置,必须放到src/test下面;在运行的(install)跳过,运行的时候会执行一遍测试类(花的时间长) 4.创建一个标准的ssm项目 项目介绍: Ssm:项目的顶级目录 ssm_common:jar包,放的是原来src_common下面的代码 ssm_service:pom,文件夹,放了api和impl的项目 ssm_service_api:jar包,放的是所有Service的接口 ssm_service_impl:jar包,所有Service的实现类 ssm_service_back:管理员后台的web服务 ssm_service_head:前台的服务 凡是依赖:如果都是java项目,会将依赖的项目打成一个jar包放到classpath中, 如果是web项目,会将依赖的项目打成一个jar包,放到web-inf/lib中 特别的图 创建完以后如下图: 添加依赖 5.搭建ssm 5.1.创建数据库 5.2.创建项目:确定项目可以在tomcat上运行 5.3.添加Spring 添加jar包 添加JAR包 增加版本的常量 在不同的项目中可以使用不同的版本-这种情况不允许 添加配置文件 写测试代码 如下图: 结论: ~将原来的原始的项目,变成maven项目 ~相同的代码,不同的环境,将项目跑起来 5.4.添加Mybatis 将service折成了两个项目:service-api,和service-impl Service-api;放的是Controller层使用到的对象;Service的接口引用,Util,POJO, Service-impl:放的是调用Dao层的对象; 目前来看:我们的web服务都依赖了api服务和impl服务,在将来引用dubbo的时候,web服务只依赖api服务,不依赖Impl
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值