使用Maven有段时间了,只能感慨真是个好东西,让我从传统模式体会到了严谨、规范、敏捷、方便的特性。
如果你懂Maven或许看过Juven翻译的《Maven权威指南》;
发个牢骚:由于Maven的出身问题导致学习曲线陡峭,所有有些人就开始说Maven不好用;原因有二:一是排斥Maven,二是没有耐心和精下心来学习,引用老毛的话来提醒我说的那些人:
没有调查就没有发言权
到了Maven这里就是(适用于技术方面):
没有深入学习也没有发言权
如果Maven不好那么Spring、Hibernate这些大家经常使用的框架为什么还是从ant转移到Maven?
如果Maven不好那么为什么国外大多数项目都在使用Maven呢?
原因自己考虑,我不废话!我的这些话就是告诫那些信口雌黄的人。
详细属性Maven的童鞋们都看过《Maven权威指南》,里面也讲解如何搭建多模块的Maven项目,但是那个毕竟是比较简单的,在实际应用中就有点水土不服了;
后来又参考了Juven的一篇《Maven最佳实践:划分模块》博文,相对权威指南来说介绍的比较详细了,但是这还是不能满足我真正在企业应用的需求,等你看完Juven的博文后再看看下面这个实际应用中的项目布局有什么异同:
OK,现在应该看出来有什么不同了,我的项目结构比权威指南里面的介绍复杂、比Juven的那篇文章说的也复杂,接下来再看看这张图片:
无图无真相,有图才给力:(如果想真正了解多模块那么请先看着图片和说明揣摩一下含义……)
声明:由于是本例是根据实际应用的项目来分析的,所以会比之前说的教程和Juven的文章实例复杂一些。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.wsria</groupId> <artifactId>dn-pb</artifactId> <version>1.0.5-SNAPSHOT</version> <name>Denong Point Bank</name> <packaging>pom</packaging> <!-- 设定团队持续集成发布包服务器 --> <distributionManagement> <repository> <id>nexus</id> <name>Team Nexus Release Repository</name> <url>http://192.168.1.111:8081/nexus/content/repositories/releases</url> </repository> <snapshotRepository> <id>nexus</id> <name>Team Nexus Snapshot Repository</name> <url>http://192.168.1.111:8081/nexus/content/repositories/snapshots</url> <uniqueVersion>false</uniqueVersion> </snapshotRepository> </distributionManagement> <scm> <connection>scm:svn:https://192.168.1.111:8443/svn/denong/pb/trunk</connection> <url>https://192.168.1.111:8443/svn/denong/pb/trunk</url> </scm> <modules> <module>parent</module> <module>common</module> <module>entity</module> <module>data</module> <module>dao</module> <module>service</module> <module>web-parent</module> <module>web-admin</module> <module>web-site</module> </modules> <build> <defaultGoal>install</defaultGoal> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-release-plugin</artifactId> <version>2.0-beta-9</version> <configuration> <autoVersionSubmodules>true</autoVersionSubmodules> </configuration> </plugin> </plugins> </build> </project>
,根据上图介绍一下:除了data目录外其他的配置文件都是在测试期间使用的,根据不同需求使用不同配置文件,例如一些不需要spring启动时初始化的数据使用applicationContext-test-no-init-sql.xml,这个没有什么规定,根据项目来设置;data目录是存放一些使用dbunit导出的xml数据文件,作用是在单元测试时的数据初始化或者利用数据文件初始化指定的数据库,一般这些数据文件的类型包括:数据字典、系统配置参数等
parent不负责管理子模块,只是被子模块集成,千万不要和denong-pb目录的pom.xml混淆
直观教程图片最给力:
maven-release-plugin是经常使用的插件,这里简单介绍一下,要点:
<scm> <connection>scm:svn:https://192.168.1.111:8443/svn/denong/pb/trunk/模块名称</connection> <url>https://192.168.1.111:8443/svn/denong/pb/trunk/模块名称</url> </scm>
上面的scm配置在每一个模块中存在,因为每一个模块再svn目录中有单独的目录;
但是parent模块有点不同,因为除了parent模块其他子模块需要继承parent,如下代码:
<parent> <groupId>com.wsria</groupId> <artifactId>parent</artifactId> <version>1.0.5-SNAPSHOT</version> <relativePath>../parent/pom.xml</relativePath> </parent> <artifactId>dn-pb-entity</artifactId>
parent模块设定了一些被子模块集成的插件,maven-release-plugin当然也在列,除了GAV之外最重要的就是tagBase标签:
<!-- release插件 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-release-plugin</artifactId> <version>2.0-beta-9</version> <configuration> <tagBase>https://192.168.1.111:8443/svn/denong/pb/tags/</tagBase> <username>${svn.name}</username> <password>${svn.pwd}</password> </configuration> </plugin>
本地的settings.xml中配置(替换${svn.name}和${svn.pwd},也就是svn提交时的用户名和密码):
<settings> ... <profiles> <profile> <id>denong-product</id> <properties> <svn.name>kafeitu</svn.name> <svn.pwd>123456</svn.pwd> </properties> </profile> </profiles> ... </settings>
在denong-pb目录中执行命令:
D:\wsria\projects\denong\denong-pb>mvn release:prepare -Pdenong-product
在svn中自动打的tag结构为:
D:\wsria\projects\denong\denong-pb>mvn release:perform
如果你够细心可能发现了上面出现了relativePath属性,这个再多模块的配置中经常遇到的问题,根据目前的案例来说子模块和parent是同级的目录,但是每个子模块又都需要继承parent模块的一些配置,比如上面介绍的到common模块会使用如下配置:
<parent> <groupId>com.wsria</groupId> <artifactId>parent</artifactId> <version>1.0.5-SNAPSHOT</version> </parent> <artifactId>common</artifactId>
现在问题来了,在common模块下执行命令:mvn compile,得到的结果中包含了警告信息:
[WARNING] ‘parent.relativePath’ points at com.wsria:dn-pb instead of com.wsria:dn-pb-parent, please verify your project structure @ line 4, column 10
意思是找不到dn-pb-parent这个模块……因为maven不知道dn-pb-parent模块存在的位置才会导致警告信息的出现,解决办法是手动指定dn-pb-parent模块的位置,所以最终的解决办法是在parent标签中加入:
<relativePath>../parent/pom.xml</relativePath>
这样maven就知道继承的parent的具体位置了,
relativePath默认值为../pom.xml,参考:http://maven.apache.org/ref/3.0/maven-model/maven.html
完整的parent继承配置:
<parent> <groupId>com.wsria</groupId> <artifactId>dn-pb-parent</artifactId> <version>1.0.5-SNAPSHOT</version> <relativePath>../parent/pom.xml</relativePath> </parent> <artifactId>dn-pb-common</artifactId>
现在运行mvn命令一切正常了;
记得每一个继承parent模块的子模块都需要添加relativePath设置
一般我们在开发web模块的时候会启用tomcat或者jboss的debug模式来断点调试应用,但是你会发现如果web模块依赖了service模块想进入service模块debug但是eclipse却告诉你找不到class的源码,解决办法:
把service模块加入到Build Path的Project列表中
如何布局是根据每一个项目组的安排定义的,比如
怎么布局需要根据项目实际情况来定义,当然要考虑到单个子模块的重复利用,例如service模块在本例中被web-admin和web-site模块使用,如果以后再加入webservice模块那么webservice也要依赖,或许还有命令行(command)模块也要依赖
这是一篇难产的文章,有些原因影响经过了3个晚上才出世,呵呵
有不对的地方请留言以改正;
分享这篇文章的目的就是给刚刚接触或者正需要maven多模块布局的童鞋们参考,希望能对你有帮助,谢谢关注!
原创文章,转载请注明: 转载自what is the RIA? just it…||咖啡兔
本文链接地址: Maven多模块布局实例详解