Maven学习总结(14)——Maven 多模块项目如何分工?
一、开场白
使用Maven有段时间了,只能感慨真是个好东西,让我从传统模式体会到了严谨、规范、敏捷、方便的特性。
如果你懂Maven或许看过Juven翻译的《Maven权威指南》;
发个牢骚:由于Maven的出身问题导致学习曲线陡峭,所有有些人就开始说Maven不好用;原因有二:一是排斥Maven,二是没有耐心和精下心来学习,引用老毛的话来提醒我说的那些人:
没有调查就没有发言权
到了Maven这里就是(适用于技术方面):
没有深入学习也没有发言权
如果Maven不好那么Spring、Hibernate这些大家经常使用的框架为什么还是从ant转移到Maven?
如果Maven不好那么为什么国外大多数项目都在使用Maven呢?
原因自己考虑,我不废话!我的这些话就是告诫那些信口雌黄的人。
二、多模块布局概述
详细属性Maven的童鞋们都看过《Maven权威指南》,里面也讲解如何搭建多模块的Maven项目,但是那个毕竟是比较简单的,在实际应用中就有点水土不服了;
后来又参考了Juven的一篇《Maven最佳实践:划分模块》博文,相对权威指南来说介绍的比较详细了,但是这还是不能满足我真正在企业应用的需求,等你看完Juven的博文后再看看下面这个实际应用中的项目布局有什么异同:
Maven多模块布局概图
OK,现在应该看出来有什么不同了,我的项目结构比权威指南里面的介绍复杂、比Juven的那篇文章说的也复杂,接下来再看看这张图片:
plexus-security项目结构
上面这张图片是我在写这篇文章的时候刚刚找到的:《按需构建多模块,玩转Maven反应堆》,和上面的Maven多模块布局概图对比一下是不是基本一样?真是后悔当初怎么没有看到Juven的这篇文章,后来把hibernate的项目checkout下来分析他的maven多模块结构布局然后再结合实际应用得出的Maven多模块布局概图。
OK,现在你对多模块布局有了初步的印象了,接下来才是重点,逐个击破、逐个分析。
三、多模块布局详解
无图无真相,有图才给力:(如果想真正了解多模块那么请先看着图片和说明揣摩一下含义……)
Maven多模块布局概述图
声明:由于是本例是根据实际应用的项目来分析的,所以会比之前说的教程和Juven的文章实例复杂一些。
denong-pb:先看实例pom.xml:
- 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
<?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>
bin:可有可无,存放一些maven的命令批处理文件或者快捷bat文件,比如本地install项目或者打包根据产品profile(在模块中配置id为product的profile)打包war;
common:估计有一些经验的人都会把一些常用的工具类封装起来,由经验丰富的人来维护到common模块中作为技术沉淀和公司的公共类库,方便大家快速开发使用。当然实际应用中可能会使用公司已经存在的common模块,然后单个项目中可能会再加入一个common模块,一般公司的common包都是这么积累下来的;
dao:每个模块的数据存取类,因为本项目是根据springside基础上构建的,所以都是继承HibernateDao,如果涉及到大数据量或者存储过程的调用会再加入相应的*JdbcDao;
data:
data模块结构
,根据上图介绍一下:除了data目录外其他的配置文件都是在测试期间使用的,根据不同需求使用不同配置文件,例如一些不需要spring启动时初始化的数据使用applicationContext-test-no-init-sql.xml,这个没有什么规定,根据项目来设置;data目录是存放一些使用dbunit导出的xml数据文件,作用是在单元测试时的数据初始化或者利用数据文件初始化指定的数据库,一般这些数据文件的类型包括:数据字典、系统配置参数等
entity:这里说一下JPA注解的实体工具,开始我使用的是eclipse3.6的JPA工具,但是发现有些属性加不上@Column注解很是郁闷,只能手动加入;当然你也可以使用springside中提供的hibernatetools模板生成,但是我还是希望在生成期间能完全受控,所以最好想到了MyEclipse,配置好数据源然后从数据库中逆向生成JPA,所有字段都正确配置;
parent:这里着重介绍一下,此模块是所有子模块需要继承的超级POM,举个例子容易理解:把本项目(denong-pb)当做是Java语言,那么parent模块就是Object类,此模块只负责定影其他子模块需要使用的一些公共设置,谨记:
parent不负责管理子模块,只是被子模块集成,千万不要和denong-pb目录的pom.xml混淆
service:就是业务处理类,供web模块调用;
web-parent:供web*模块继承,例如前后台都需要调用的Action接口,像数据字典、地区信息、系统属性等
web-admin:系统的后台管理程序,使用了struts2的convention插件;
web-site:系统网站部分,同样使用了struts2的convention插件,集成单点登录功能
四、模块之间依赖关系
直观教程图片最给力:
五、和SVN的整合——maven-release-plugin
maven-release-plugin是经常使用的插件,这里简单介绍一下,要点:
每个模块的scm配置:
- 1234
<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,如下代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<?xml version= "1.0" ?> <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> <!-- 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提交时的用户名和密码):
1
2
3
4
5
6
7
8
9
10
11
|
<?xml version= "1.0" ?> <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模块会使用如下配置:
1
2
3
4
5
6
|
<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继承配置:
1
2
3
4
5
6
7
|
<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设置
七、多模块开发期间Debug
一般我们在开发web模块的时候会启用tomcat或者jboss的debug模式来断点调试应用,但是你会发现如果web模块依赖了service模块想进入service模块debug但是eclipse却告诉你找不到class的源码,解决办法:
把service模块加入到Build Path的Project列表中
八、其他方案
如何布局是根据每一个项目组的安排定义的,比如
一个项目组分模块开发的话或许不像本例一样分模块而是把每一层都集中在一个项目中
或许web模块单独一个子模块,其他的entyty、dao、service集中在一个子模块model中
怎么布局需要根据项目实际情况来定义,当然要考虑到单个子模块的重复利用,例如service模块在本例中被web-admin和web-site模块使用,如果以后再加入webservice模块那么webservice也要依赖,或许还有命令行(command)模块也要依赖
九、总结
我的项目结构如下:
项目划分为核心、辅助及视图三大模块,其中核心模块按功能划分为各个小模块,视图模块主要是后端WEB和各前端WEB;
trade是整个父级模块,trade-code是核心模块的父级模块,继承trade模块,trade-help是辅助模块的父级模块,继承trade模块,trade-view是视图模块的父级模块,继承trade模块;
项目整个文件结构是树型结构;
Maven学习总结(14)——Maven 多模块项目如何分工?的更多相关文章
- (转)Maven学习总结(二)——Maven项目构建过程练习
孤傲苍狼 只为成功找方法,不为失败找借口! Maven学习总结(二)——Maven项目构建过程练习 上一篇只是简单介绍了一下maven入门的一些相关知识,这一篇主要是体验一下Maven高度自动化构建项 ...
- (转)Maven学习总结(六)——Maven与Eclipse整合
孤傲苍狼只为成功找方法,不为失败找借口! Maven学习总结(六)——Maven与Eclipse整合 一.安装Maven插件 下载下来的maven插件如下图所示:,插件存放的路径是:E:/MavenP ...
- (转)Maven学习总结(四)——Maven核心概念
孤傲苍狼只为成功找方法,不为失败找借口! Maven学习总结(四)——Maven核心概念 一.Maven坐标 1.1.什么是坐标? 在平面几何中坐标(x,y)可以标识平面中唯一的一点. 1.2.Mav ...
- MAVEN学习笔记之Maven生命周期和插件简介(3)
MAVEN学习笔记之Maven生命周期和插件简介(3) clean compile site三套生命周期相互独立. clean pre-clean 执行清理前的工作 clean 清理上一次构建生成的所 ...
- MAVEN学习笔记之Maven插件的应用(4)
MAVEN学习笔记之Maven插件的应用(4) <build> <pluginManagement> <plugins> <plugin> <gr ...
- Maven学习3-使用Maven构建项目
转自:http://www.cnblogs.com/xdp-gacl/p/4240930.html maven作为一个高度自动化构建工具,本身提供了构建项目的功能,下面就来体验一下使用maven构建项 ...
- Maven学习 (三) 使用m2eclipse创建web项目
1.首先确认你的eclipse已经安装好m2eclipse的环境,可以参照上两篇Maven学习内容 2.新建一个maven的项目 3.下一步默认配置,使用默认的工作空间,或者你可以自己选择其他的空间 ...
- Maven学习总结(十一)——Maven项目对象模型pom.xml文件详解
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...
- Maven学习总结(二)——Maven项目构建过程练习
上一篇只是简单介绍了一下maven入门的一些相关知识,这一篇主要是体验一下Maven高度自动化构建项目的过程 一.创建Maven项目 1.1.建立Hello项目 1.首先建立Hello项目,同时建立M ...
- Maven学习(十一)-----使用Maven创建Web应用程序项目
使用Maven创建Web应用程序项目 用到的技术/工具: Maven 3.3.3 Eclipse 4.3 JDK 8 Spring 4.1.1.RELEASED Tomcat 7 Logback 1. ...
随机推荐
- JS控制光标定位,定位到文本的某个位置
这是一个数字密码,要能够智能的跳转到文本的某个位置,就需要通过JS来控制跳转! 1.onkeyup监听 <input class="put" id="number- ...
- .net 项目分层及规范
1.解决方案命名:公司简称+产品名称.如ABCSOft.BBS 2.解决方案文件夹:以数字排序例如:01.Web表示页面层:02.IBusinessLogic表示业务逻辑接口:03.Bussin ...
- 基于CANopen DSP402的运动控制笔记
常用的mode of operation 有以下几种: 控制字 control word: 6--------------7---------------15--------------------7 ...
- 添加 validate 验证规则
上篇文章链接:http://blog.csdn.net/chenmoimg_/article/details/71191476 修改 msg.js $.extend($.validator.messa ...
- 《三》build 快速创建模块
一.将build.php文件复制一份放在 application目录下 二.修改build.php文件代码 <?php return [ 'home' => [ //需要生成的目录 '__ ...
- python 发送邮件 <QQ+腾讯企业邮箱>
一.使用QQ邮箱或者腾讯企业邮箱 python 发送邮件属于网络编程方向的,在工作中,我需要经常用邮件来检测我的程序运行状况.使用起来十分方便,这里我就用腾讯企业邮箱作为我的收发邮箱来使用. 使用py ...
- sigprocmask, sigpending, sigsuspend的用法
sigset_t set sigemptyset(&set) :清空阻塞信号集合变量 sigfillset(&set) :添加所有的信号到阻塞集合变量里 sigaddset(& ...
- Transport Tablespace Set(三) ----transport single tablespace
源端字符集与endian查看: SQL> select userenv('language') from dual; USERENV('LANGUAGE') SIMPLIFIED CHINESE ...
- Hadoop-2.6.0上的C的API訪问HDFS
在通过Hadoop-2.6.0的C的API訪问HDFS的时候,编译和执行出现了不少问题,花费了几天的时间,上网查了好多的资料,最终还是把问题给攻克了 參考文献:http://m.blog.csdn.n ...
- SSM(spring,springMVC,Mybatis)框架的整合
这几天想做一个小项目,所以搭建了一个SSM框架. 1.基本概念 1.1.Spring Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Joh ...