1.介绍
1.1 背景问题
我们在java 开发中,最常用的模式是MVC, 根据理论讲到 各层完全独立,犹如组件一样,比如:今天DAO层用的Hibernate,明天你可以替换成Mybatis, 控制层今天用struts,也可以替换成springmvc,或者swing项目.这些我们只是强调这种思想,但是我们从来没有真正理解过,因为项目开发我们很少遇到这样场景,代码中我经常会为了寻求简便,或者没注意,各层交叉调用,都会导致后期维护困难。学习maven模块分层是一个电商项目中,一个平台会分为很多个子系统,比如会分为:前台、运营管理后台、卖家管理后台、监控、统计、定时任务等辅助系统。这些子系统之间独立部署切又有一定联系。对于这些系统 通常我们业务层和持久层代码重用比较多,但是系统如果独立,我们需要把相关代码copy一份过去,这样带来代码的维护难度。
1.2 maven 模块介绍
用Maven管理的真实的项目都应该是分模块的,每个模块都对应着一个pom.xml。它们之间通过继承和聚合(也称作多模块,multi-module)相互关联.模块之间关系结构比较清晰。例如:
一个简单的Maven模块结构是这样的:
---- app-parent
|-- pom.xml (pom)
|
|-- app-util
| |-- pom.xml (jar)
|
|-- app-dao
| |-- pom.xml (jar)
|
|-- app-service
| |-- pom.xml (jar)
|
|-- app-web
|-- pom.xml (war)
app-dao --> app-util
app-service --> app-dao
用项目层次的划分替代包层次的划分能给我们带来如下好处:
- 方便重用,如果你有一个新的swing项目需要用到app-dao和app-service,添加对它们的依赖即可,你不再需要去依赖一个WAR。而有些模块,如app-util,完全可以渐渐进化成公司的一份基础工具类库,供所有项目使用。这是模块化最重要的一个目的。
- 由于你现在划分了模块,每个模块的配置都在各自的pom.xml里,不用再到一个混乱的纷繁复杂的总的POM中寻找自己的配置。
- 如果你只是在app-dao上工作,你不再需要build整个项目,只要在app-dao目录运行mvn命令进行build即可,这样可以节省时间,尤其是当项目越来越复杂,build越来越耗时后。
- 某些模块,如app-util被所有人依赖,但你不想给所有人修改,现在你完全可以从这个项目结构出来,做成另外一个项目,svn只给特定的人访问,但仍提供jar给别人使用。
- 多模块的Maven项目结构支持一些Maven的更有趣的特性(如DepencencyManagement),这留作以后讨论。
2.Maven模块配置
这里我们通过eclipse来快速创建maven, 如果使用eclipse创建 预先要安装 M2E - Maven Integration for Eclipse 组件。
2.1 创建父工程 app-parent
点击右键New-选择Maven,选择 Maven project. 这Maven project 和 Maven Module 区别 在 project 是父工程 ,Module 是创建子工程.
填写 group id, artifact id 这里packageing 选择 pom
2.2 创建子工程 app-service, app-dao, app-util,app-web
点击app-parent 右键 创建 maven module 子工程,这里除了app-web 选择 war, 其它类型都选择jar
几个子工程创建完后,结构目录如下所示:
3. pom.xml 配置文件
3.1 app-parent
<modelVersion>4.0.0</modelVersion>
<groupId>com.bswan</groupId>
<artifactId>app-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>app-web</module>
<module>app-service</module>
<module>app-dao</module>
<module>app-util</module>
</modules>
<build>
<defaultGoal>compile</defaultGoal>
</build>
3.2 app-web
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.bswan</groupId>
<artifactId>app-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>app-web</artifactId>
<packaging>war</packaging>
<name>app-web Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>com.bswan</groupId>
<artifactId>app-service</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<defaultGoal>compile</defaultGoal>
<finalName>app-web</finalName>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>8.1.8.v20121106</version>
<configuration>
<stopKey>stop</stopKey>
<stopPort>5599</stopPort>
<webAppConfig>
<contextPath>/</contextPath>
</webAppConfig>
<scanIntervalSeconds>5</scanIntervalSeconds>
<connectors>
<connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
<port>8080</port>
<maxIdleTime>60000</maxIdleTime>
</connector>
</connectors>
</configuration>
</plugin>
</plugins>
</build>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.bswan</groupId>
<artifactId>app-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>app-service</artifactId>
<dependencies>
<dependency>
<groupId>com.bswan</groupId>
<artifactId>app-dao</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
3.4 app-dao
同上.
3.5 app-util
同上.
4. 案例演示
app-parent.zip
下载后,可以导入eclipse,也可以直接运行执行,
在app-parent目录下执行
mvn clean package -Dmaven.test.skip=true
进入 app-web
mvn jetty:run
打开浏览器访问:http://localhost:8080/
5.结语
当然这个过程还有很多要调整和布置,并且一开始使用会非常别扭。导入,编译,执行都不方便,但这些都不是问题,可以在此基础上慢慢摸索.