`

Maven多模块布局实例详解

阅读更多

Maven多模块布局实例详解

一、开场白

使用Maven有段时间了,只能感慨真是个好东西,让我从传统模式体会到了严谨、规范、敏捷、方便的特性。
如果你懂Maven或许看过Juven翻译的《Maven权威指南》;
发个牢骚:由于Maven的出身问题导致学习曲线陡峭,所有有些人就开始说Maven不好用;原因有二:一是排斥Maven,二是没有耐心和精下心来学习,引用老毛的话来提醒我说的那些人:

没有调查就没有发言权

到了Maven这里就是(适用于技术方面):

没有深入学习也没有发言权

如果Maven不好那么Spring、Hibernate这些大家经常使用的框架为什么还是从ant转移到Maven?
如果Maven不好那么为什么国外大多数项目都在使用Maven呢?
原因自己考虑,我不废话!我的这些话就是告诫那些信口雌黄的人。

二、多模块布局概述

详细属性Maven的童鞋们都看过《Maven权威指南》,里面也讲解如何搭建多模块的Maven项目,但是那个毕竟是比较简单的,在实际应用中就有点水土不服了;
后来又参考了Juven的一篇《Maven最佳实践:划分模块》博文,相对权威指南来说介绍的比较详细了,但是这还是不能满足我真正在企业应用的需求,等你看完Juven的博文后再看看下面这个实际应用中的项目布局有什么异同:

Maven多模块布局概图

Maven多模块布局概图

OK,现在应该看出来有什么不同了,我的项目结构比权威指南里面的介绍复杂、比Juven的那篇文章说的也复杂,接下来再看看这张图片:

plexus-security项目结构

plexus-security项目结构



上面这张图片是我在写这篇文章的时候刚刚找到的:《按需构建多模块,玩转Maven反应堆》,和上面的Maven多模块布局概图对比一下是不是基本一样?真是后悔当初怎么没有看到Juven的这篇文章,后来把hibernate的项目checkout下来分析他的maven多模块结构布局然后再结合实际应用得出的Maven多模块布局概图
OK,现在你对多模块布局有了初步的印象了,接下来才是重点,逐个击破、逐个分析。

 

三、多模块布局详解

无图无真相,有图才给力:(如果想真正了解多模块那么请先看着图片和说明揣摩一下含义……)

 

Maven多模块布局概述图

Maven多模块布局概述图

声明:由于是本例是根据实际应用的项目来分析的,所以会比之前说的教程和Juven的文章实例复杂一些。

  1. denong-pb:先看实例pom.xml
    <?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>
  2. bin可有可无,存放一些maven的命令批处理文件或者快捷bat文件,比如本地install项目或者打包根据产品profile(在模块中配置id为product的profile)打包war;
  3. common:估计有一些经验的人都会把一些常用的工具类封装起来,由经验丰富的人来维护到common模块中作为技术沉淀和公司的公共类库,方便大家快速开发使用。当然实际应用中可能会使用公司已经存在的common模块,然后单个项目中可能会再加入一个common模块,一般公司的common包都是这么积累下来的;
  4. dao:每个模块的数据存取类,因为本项目是根据springside基础上构建的,所以都是继承HibernateDao,如果涉及到大数据量或者存储过程的调用会再加入相应的*JdbcDao;
  5. data
    data模块结构

    data模块结构

    ,根据上图介绍一下:除了data目录外其他的配置文件都是在测试期间使用的,根据不同需求使用不同配置文件,例如一些不需要spring启动时初始化的数据使用applicationContext-test-no-init-sql.xml,这个没有什么规定,根据项目来设置;data目录是存放一些使用dbunit导出的xml数据文件,作用是在单元测试时的数据初始化或者利用数据文件初始化指定的数据库,一般这些数据文件的类型包括:数据字典、系统配置参数等

  6. entity:这里说一下JPA注解的实体工具,开始我使用的是eclipse3.6的JPA工具,但是发现有些属性加不上@Column注解很是郁闷,只能手动加入;当然你也可以使用springside中提供的hibernatetools模板生成,但是我还是希望在生成期间能完全受控,所以最好想到了MyEclipse,配置好数据源然后从数据库中逆向生成JPA,所有字段都正确配置;
  7. parent:这里着重介绍一下,此模块是所有子模块需要继承的超级POM,举个例子容易理解:把本项目(denong-pb)当做是Java语言,那么parent模块就是Object类,此模块只负责定影其他子模块需要使用的一些公共设置,谨记:

    parent不负责管理子模块,只是被子模块集成,千万不要和denong-pb目录的pom.xml混淆

  8. service:就是业务处理类,供web模块调用;
  9. web-parent:供web*模块继承,例如前后台都需要调用的Action接口,像数据字典、地区信息、系统属性等
  10. web-admin:系统的后台管理程序,使用了struts2的convention插件;
  11. web-site:系统网站部分,同样使用了struts2的convention插件,集成单点登录功能

四、模块之间依赖关系

直观教程图片最给力:

Maven多模块关系依赖图

Maven多模块关系依赖图

 

五、和SVN的整合——maven-release-plugin

maven-release-plugin是经常使用的插件,这里简单介绍一下,要点:

  1. 每个模块的scm配置
    <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结构为:

    maven-release-plugin执行release:prepare后的svn结构

    maven-release-plugin执行release:prepare后的svn结构


    接下来就可以执行命令:

     

    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设置

七、多模块开发期间Debug

一般我们在开发web模块的时候会启用tomcat或者jboss的debug模式来断点调试应用,但是你会发现如果web模块依赖了service模块想进入service模块debug但是eclipse却告诉你找不到class的源码,解决办法:

把service模块加入到Build Path的Project列表中

八、其他方案

如何布局是根据每一个项目组的安排定义的,比如

  1. 一个项目组分模块开发的话或许不像本例一样分模块而是把每一层都集中在一个项目中
  2. 或许web模块单独一个子模块,其他的entyty、dao、service集中在一个子模块model中

怎么布局需要根据项目实际情况来定义,当然要考虑到单个子模块的重复利用,例如service模块在本例中被web-admin和web-site模块使用,如果以后再加入webservice模块那么webservice也要依赖,或许还有命令行(command)模块也要依赖

九、结束语

这是一篇难产的文章,有些原因影响经过了3个晚上才出世,呵呵
有不对的地方请留言以改正;
分享这篇文章的目的就是给刚刚接触或者正需要maven多模块布局的童鞋们参考,希望能对你有帮助,谢谢关注!

原创文章,转载请注明: 转载自what is the RIA? just it…||咖啡兔

分享到:
评论
1 楼 tsmoon 2012-03-31  

相关推荐

    maven window下安装包

    第14章:灵活的构建/14.2 Maven属性的使用/14.2.3 属性解析/14.2.3.3 实例完整源代码 第14章:灵活的构建/14.3 激活属性文件的方法/14.3.1 属性文件概念 第14章:灵活的构建/14.3 激活属性文件的方法/14.3.2 命令行...

    maven2书中代码 mvn-examples-1.0

    【 Maven2 详解:mvn-examples-1.0 代码实例】 Maven 是一个强大的项目管理和构建工具,尤其在Java开发中广泛使用。`mvn-examples-1.0`是一个示例集合,用于展示Maven2的核心功能和用法。这个压缩包中的代码例子...

    springside3.3.4 实例

    3. **注释详解**:实例中的代码包含丰富的注释,这对于学习和理解 SpringSide 的工作原理至关重要。注释详细解释了每个类、方法的作用,以及它们在整个系统中的角色。 4. **Spring 框架集成**:SpringSide 基于 ...

    jsf+spring 实例

    JSF组件库包括一系列可重用的UI组件,如按钮、文本框、表格等,开发者可以通过XML配置或Java代码来创建和布局页面。JSF通过EL(Expression Language)进行数据绑定,简化了页面和后台Bean的交互。 **2. Spring框架...

    springside4 quickstart

    在SpringSide 4中,通常会创建一个或多个模块(Module),每个模块负责特定的功能。例如,可以创建一个UserModule来处理用户相关的业务逻辑,通过定义Service接口和实现类,以及对应的DAO操作数据库。此外,还可以...

    基于javaweb的学生信息管理系统.zip

    《基于JavaWeb的学生信息管理系统详解》 在信息技术日益发展的今天,学生信息管理系统的构建成为教育机构提高工作效率、优化管理流程的重要工具。本项目名为“基于JavaWeb的学生信息管理系统”,其核心是利用...

    基于ssm+jsp电子竞技管理平台源码数据库.zip

    总的来说,“基于SSM+JSP的电子竞技管理平台源码数据库”项目是一个完整的Java Web应用实例,它涵盖了后端开发的多个核心技术,对学习和实践Java Web开发具有很高的参考价值。通过深入研究这个项目,开发者不仅可以...

    Coffee_house

    《咖啡店管理系统详解》 咖啡店管理系统的开发旨在提高咖啡店运营效率,通过GUI(图形用户界面)提供直观的操作体验,让日常业务处理更加便捷。本文将深入探讨该系统的核心功能、设计思路以及实现技术。 一、系统...

    Java SSM基于HTML仿淘宝购物系统【优质毕业设计、课程设计项目分享】

    1. **Java SSM框架详解** - **Spring**:这是一个全面的Java应用开发框架,核心功能是依赖注入(DI),它简化了组件之间的耦合,使得测试和维护变得容易。 - **SpringMVC**:是Spring框架的一个模块,用于构建Web...

    基于ssm+jsp的珠宝购物网站系统.zip

    《基于SSM+JSP的珠宝购物网站系统详解》 在现代电子商务领域,构建一个功能齐全、用户体验良好的购物网站已经成为企业必备的工具。本篇文章将深入解析“基于SSM+JSP的珠宝购物网站系统”,阐述其核心技术和设计思想...

    Java语言+基于SSM超市订单管理系统(毕业设计、课程设计使用).zip

    《基于Java SSM的超市订单管理系统详解》 Java语言作为企业级应用开发的重要工具,广泛应用于各类管理系统的设计与实现。本系统——“基于SSM的超市订单管理系统”就是这样一个实例,它不仅适用于毕业设计和课程...

    springboot+蔬菜商城农产品销售系统+毕设.zip

    《基于SpringBoot的蔬菜商城农产品销售系统开发详解》 在当今信息化时代,电子商务已经渗透到各行各业,农业领域也不例外。本文将深入探讨一个基于SpringBoot框架的“蔬菜商城农产品销售系统”,该系统适用于毕业...

    Jetspeed2之安装配置

    ### Jetspeed2之安装配置知识点详解 #### 一、如何安装Jetspeed2 **准备工作:** 在安装Jetspeed2之前,需要确保系统中已经安装了JDK 1.5,并且正确设置了`JAVA_HOME`环境变量指向JDK的安装路径。 **安装模式:*...

    安卓QQ相关相关-androidstudioQQ第三方登录demo测试可以运行登录有返回值和退出.zip

    - "下载更多打包源码~.url"可能是指向更多类似项目的链接,便于开发者学习更多实例。 - "Open_sample"可能是一个示例代码文件,展示如何打开QQ登录的界面或者处理登录返回的数据。 以上是关于Android应用集成QQ第...

    基于springboot-layui-mysql的血库管理系统

    《基于SpringBoot-Layui-Mysql的血库管理系统详解》 在信息技术日益发达的今天,管理系统已经成为各行各业不可或缺的一部分。本文将深入探讨一个基于SpringBoot、Layui和Mysql技术的血库管理系统,旨在帮助读者理解...

    2017年尚学堂Java培训课程大纲.docx

    - **Struts2多模块配置**:掌握多模块项目的配置方法。 - **Struts2标签库及OGNL表达式**:学习Struts2提供的标签库及Object-Graph Navigation Language(OGNL)表达式的使用。 ##### 3.3 Mybatis框架 - **MyBatis...

    [其他类别]MeyboMail Web(Java)开源简化_meybomailweb.rar

    MeyboMail Web的源码结构通常会遵循Maven或Gradle的标准项目布局,包括src/main/java、src/main/resources、src/test/java等目录。这些目录分别存放Java源代码、资源配置文件以及测试代码。 2. **核心技术栈** - ...

    Java写的拼图游戏.zip

    《Java编程实现拼图游戏详解》 在信息技术领域,编程语言是创造各种应用程序的基础,而Java作为一门广泛应用的编程语言,被广泛应用于各个领域,包括游戏开发。本项目"Java写的拼图游戏.zip"就是一个很好的实例,...

    JSP_SSM_Bootstrap驾校管理系统可升级SpringBoot毕业源码案例设计.zip

    1. **SSM框架详解**: - **Spring**:作为核心容器,管理应用中的对象,提供依赖注入(DI)和面向切面编程(AOP)功能,简化了Java应用的开发。 - **SpringMVC**:是Spring框架的一个模块,用于处理HTTP请求和响应...

    明日JSP新闻系统(毕业论文)

    技术开发的新闻信息发布与管理系统,主要用于实现新闻的发布、浏览、搜索等功能,是毕业生在完成学业时可能会选择的项目课题,也是理解Web应用程序开发的一个典型实例。在这个系统中,JSP作为前端展示层,与后端的...

Global site tag (gtag.js) - Google Analytics