笔者在网上看到了太多使用maven进行多模块构建的文档,主要是对项目进行横向切割为不同的模块,每个模块为一个单一maven module project,现以一个项目举例,来说明其大致步骤;然后,通过对该项目进行纵向切割,说明其配置方式,并比较两者之间异同点。
1.项目需求
某公司现在开发一个幼儿园管理系统(项目名称:wo-baby)整个系统的子系统包结构大致如下:
com.qfedu.wo.common
:该包提供整个项目的公共工具类等通用功能
com.qfedu.wo.sys
:系统管理子系统完成整个系统权限管理,包括如下子包
com.qfedu.wo.sys.controller
com.qfedu.wo.sys.service
com.qfedu.wo.sys.dao
com.qfedu.wo.sys.entity
com.qfedu.wo.baby
:幼儿园管理子系统,完成整个幼儿园管理功能,包括如下子包
com.qfedu.wo.baby.controller
com.qfedu.wo.baby.service
com.qfedu.wo.baby.dao
com.qfedu.wo.baby.entity
2.项目横向切割,分模块构建
横向切割就是按照项目的分层开发模型,对整个项目进行分模块构建,划分模块如下:
整个项目划分为5个子模块,如上图所示,各子模块对应的包如下:
wo-common:com.qfedu.wo.common
wo-web:com.qfedu.wo.sys.controller/com.qfedu.wo.baby.controller
wo-service:com.qfedu.wo.sys.service/com.qfedu.wo.baby.service
wo-dao:com.qfedu.wo.sys.dao/com.qfedu.wo.baby.dao
wo-entity:com.qfedu.wo.sys.entity/com.qfedu.wo.baby.entity
首先,构建maven主项目wo-root,其pom.xml核心配置如下,打包方式设置为pom
<modelVersion>4.0.0</modelVersion>
<groupId>com.qfedu.wo</groupId>
<artifactId>wo-root</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
其次,分别在其下建立maven module project(wo-common/wo-web/wo-service/wo-dao/wo-entity),其pom.xml中的核心配置如下:
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.qfedu.wo</groupId>
<artifactId>wo-root</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>wo-web</artifactId>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>com.qfedu.wo</groupId>
<artifactId>wo-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.qfedu.wo</groupId>
<artifactId>wo-service</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.qfedu.wo</groupId>
<artifactId>wo-entity</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
其中的关键点就是使用parent配置,继承wo-root项目中的配置;同时,添加对其他子模块的依赖。
3.纵向切割,分模块构建
横向切割中存在如下问题:
1.假如公司后续又有一项目,需要基于系统管理子系统开发,那么就需要从上述多个模块中,单独抽离系统管理的代码和页面,明显没有实现项目的充分共享
2.而且,新的项目中所有的静态资源(图片、css样式、js框架、项目通用的js代码等)都需要从之前的项目中重新拷贝一份,这样明显不是一个很好的方案
为了应对上述需求,现对整个项目进行纵向切割。
纵向切割是按照项目功能,对整个项目进行切割,划分模块如下:
整个项目划分为5个子模块,如上图所示,各子模块对应的包如下:
wo-common:com.qfedu.wo.common
,普通java项目
wo-web:包含所有公共web项目的静态资源,例如js框架、通用css样式、公司通用的js代码等,web项目
wo-sys:com.qfedu.wo.sys
,web项目
wo-baby:com.qfedu.wo.baby
,web项目
wo-root配置及各子项目的大部分配置,和上节相同,不再赘述,现以wo-sys为例,说明不同之处。
首先,继承父项目wo-root配置
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.qfedu.wo</groupId>
<artifactId>wo-root</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>wo-sys</artifactId>
<packaging>war</packaging>`
其次,添加对wo-web项目依赖,type为war,scope为runtime
<dependencies>
<dependency>
<groupId>com.qfedu.wo</groupId>
<artifactId>wo-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.qfedu.wo</groupId>
<artifactId>wo-web</artifactId>
<version>${project.version}</version>
<type>war</type>
<scope>runtime</scope>
</dependency>
...
</dependencies>
最后,需要配置maven-war-plugin插件,在运行或者发布的时候,从wo-web中拷贝静态资源
<build>
<finalName>wo-sys</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<warSourceDirectory>src/main/webapp</warSourceDirectory>
<overlays>
<overlay>
<groupId>com.qfedu.wo</groupId>
<artifactId>wo-web</artifactId>
<excludes>
<exclude>WEB-INF/lib/*</exclude>
<exclude>WEB-INF/web.xml</exclude>
</excludes>
</overlay>
</overlays>
</configuration>
</plugin>
</plugins>
</build>
wo-baby模块的配置稍有不同,它除了在运行时需要拷贝所有wo-sys项目的静态资源外,在编译时还依赖于wo-sys模块的类,所以,对wo-sys的依赖有两个,type分别为jar和war,具体依赖配置如下:
<dependencies>
<dependency>
<groupId>com.qfedu.wo</groupId>
<artifactId>wo-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.qfedu.wo</groupId>
<artifactId>wo-sys</artifactId>
<type>jar</type>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.qfedu.wo</groupId>
<artifactId>wo-sys</artifactId>
<version>${project.version}</version>
<type>war</type>
<scope>runtime</scope>
</dependency>
...
</dependencies>