多模块maven项目实践经验

以多模块的形式组织项目,乃是maven一直提倡的方式。如果使用得当,多模块可以可以帮助项目划分模块,鼓励重用,防止POM变得过于庞大,方便某个模块的构建,而不用每次都构建整个项目,并且使得针对某个模块的特殊控制更为方便(关于多模块优势的描述可以参见juvenshun的博文Maven最佳实践:划分模块http://juvenshun.iteye.com/blog/305865。)

 

虽然多模块能给项目带来诸多好处,单实际操作时常常遇到一些各种各样的增加项目复杂度的问题,导致开发的效率下降。这里总结了一些在多模块项目实践中的常见的问题和解决办法,帮助降低复杂度,减少程序员的无谓劳动。

 

  • 组织依赖

在多模块项目中,不同的模块依赖的包各自不同,而这些依赖中又往往会有一些相同的依赖。一种常见的组织方式是,每个程序员在自己负责的子模块的pom文件中加入该模块需要的依赖,然后往下进行开发。这样做会出现项目对同一个类库依赖各种不同的版本的情况,给项目带来了复杂度,同时也容易出现各种各样的问题。

 

最佳实践应该是,将可能被多个项目共同依赖的的包以及maven插件设置放在父模块的pom文件中,以dependencyManagementpluginManagement的形式进行管理。这样做,一来实现了依赖的统一管理,二来统一了项目对类库依赖的版本,减少对程序员该来的迷惑和思考。

 

  • 子模块间依赖

对于项目子模块间依赖,可以选择放到dependencyManagement中,也可以放在各自子模块的pom文件中,但需要注意的一点是,每个子模块的版本最好和整个项目的版本统一,通过在父模块pomproperties配置中设置project.version属性,各子模块依赖版本均以此为准的方式来处理。否则子模块的升级会带来各种意想不到的情况。

 

  • 版本控制

Web项目中常用到spring框架,该框架的依赖可分为spring-corespring-beans等等若干个,它们的版本号往往是统一的。如果我们因为某些原因需要改变spring的版本,需要将所有依赖的版本都进行修改,这样显然不是明智的做法。减少重复劳动的方法是,将重复存在的版本抽取出来,统一放在父模块pomproperties配置中统一管理。当日后需要变更版本时,只需要对父模块pom进行修改,便可到处生效。

 

另一个更进一步的做法是,新建一个子模块spring-dep,设置打包方式为pom,将spring相关的依赖全部放到这个子模块中,当项目需要使用spring时,只需要添加对该模块的依赖即可。这样做的好处是,spring-dep模块不仅可以在当前项目中使用,还可以放到其他的项目中,一劳永逸的解决了spring的版本问题。以此类推,也可以用这种方式对测试等等较为通用的框架依赖进行管理。

 

  • 排除单个包依赖

在使用日志系统时,如果使用到了slf4j框架,则在依赖中需要将comons-logging依赖排除,避免其和JCL-over-SLF4J发生冲突,导致不能正常打日志。为了解决这个问题,在maven仓库中对commons-logging存在99.0-does-not-exist这个版本,该版本其实空无一物,因此依赖该版本相当于什么都没有依赖。当需要排除这个依赖时,则在父模块的pom中依赖commons-logging,并将版本设为99.0-does-not-exist,即可排除该依赖。

 

这是一个较为特别的排除依赖的方法,那么,除此之外还有没有更通用一些的手段呢?答案是有的,在父模块的pom文件的dependency中设置对要排除的包的依赖,然后将其scope设置为provided,根据依赖传递性,所有子模块中对该包的依赖都以父模块pom中的定义为准,所以最终依赖将不会包含该包,也就达到了排除依赖的目的。

 

这样做虽然能够排除依赖,不过需要注意的一点是,在单元测试过程中,该依赖仍然存在,会对单元测试造成影响。

 

  • 多个spring子模块

在开发web项目时,通常会将项目分为project-webproject-serviceproject-dao等等若干个子模块。这时,可能需要在多个子模块中使用到spring框架的IoC机制,定义一些特定功能的bean。那我们如何在web子模块中识别并获取到其他子模块(比如service)的bean呢?首先,我们从部署的角度来看,无论是单模块项目,或者是多模块项目,在项目编译完成后,通常会被整体打包到一个war包中,然后将其部署到Web容器中运行,容器通过唯一的web.xml文件作为web工程配置的入口,执行这个web项目。因此,我们在需要使用spring框架的模块中配置好相应的applicationContext.xml文件(要放到src/main/resources下,这样能通过classpath轻松的找到),然后在web子模块的web.xml文件中引用这些所有的applicationContext文件。这样一来,所有的bean都能在web子模块中被识别和调用。

 

如果使用spring注解来注入类,那么一个比较好的实践是,对所有子模块的包命名相同的前缀(比如com.company.product.*),然后在web子模块的applicationContext文件中使用<context:component-scan base-package="com.company.product.*"/>,这里就能够扫描到所有com.company.product.*包下的component/controller/service,不用再在各个子模块中定义applicationContext文件。

 

  • 使用maven filter过滤WEB-INF目录下文件

Maven filter能够过滤资源(resource)文件,通过在pom文件中配置:

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

根据 properties 文件替换资源文件中的占位符。

而当需要过滤src/main/webapp/WEB-INF/目录下的文件(比如web.xml)时,不能在这里配置,因为这里是处理资源文件的,最终这些资源文件都会被放到target/classes目录下,不能满足需求,因此需要再另外做配置:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <configuration>
        <webResources>
            <webResource>
                <!-- 过滤的目录-->
                <directory>${basedir}/src/main/webapp/WEB-INF</directory>
                <includes>
                    <!-- 添加需要过滤的文件 ,支持通配符-->
                    <include>web.xml</include>
                </includes>
                <!-- 打包之后目标目录 -->
                <targetPath>WEB-INF</targetPath>
                    <filtering>true</filtering>
            </webResource>
        </webResources>
    </configuration>
</plugin>



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、付费专栏及课程。

余额充值