SSM 聚合项目搭建:多 Maven 模块项目

一、什么是 Maven 聚合父子工程

1.1 模块划分说明

hami‑parent 作为父工程(聚合工程),本身不写业务代码,只做两件事:

聚合所有子模块

使用dependencyManagement统一管理 jar 包版本

子模块分工:

|--------------|------|-------------------------------------------------------------|
| 模块名 | 打包方式 | 职责说明 |
| hami‑parent | pom | 父工程,版本管理、聚合子模块,无业务代码 |
| hami‑core | jar | 核心公共模块,model、dao、service、mapper 映射文件、工具类、逆向工程、代码生成器,被其他模块依赖 |
| hami‑console | war | 后台管理系统,只写 Controller、jsp 页面,依赖 ham‑core |
| hami‑portal | war | 前台用户门户系统,播放器、歌曲检索,只写 Controller、jsp 页面,依赖 hami‑core |
| hami‑file | war | 独立文件服务器,专门处理图片、MP3 文件上传下载 |

独立文件服务器,专门处理图片、MP3 文件上传下载

核心优势:公共的 dao、service 只写一份放在 hami‑core,后台、前台直接依赖 jar 复用,避免重复拷贝代码。文件服务器独立部署,实现静态资源和业务服务解耦。

1.2 运行逻辑

hami‑core 编译打包生成 jar 包

hami‑console、hami‑portal、hami‑file 引入 hami‑core 依赖

各个 war 模块分别部署 tomcat,实现多服务分开运行。

项目目录结构截图参考:

二、父工程 hami‑parent pom.xml 配置

父工程 packaging 必须是pom,使用<modules>标签配置需要聚合的子模块;

dependencyManagement只是声明版本,不会实际引入依赖,子模块需要使用才需要再写 dependency。

复制代码
<?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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.tx.music</groupId>
    <artifactId>ham-parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!--父工程打包类型必须pom-->
    <packaging>pom</packaging>

    <!--聚合子模块,填写子模块文件夹名字-->
    <modules>
        <module>ham-core</module>
        <module>ham-console</module>
        <module>ham-portal</module>
        <module>ham-file</module>
    </modules>

    <!--统一管理版本号,子模块不需要写version-->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <spring.version>5.0.2.RELEASE</spring.version>
        <slf4j.version>1.6.6</slf4j.version>
        <log4j.version>1.2.12</log4j.version>
        <mysql.version>5.1.6</mysql.version>
        <mybatis.version>3.4.5</mybatis.version>
        <aspectj.version>1.6.8</aspectj.version>
        <junit.version>4.12</junit.version>
        <servlet.version>2.5</servlet.version>
        <jsp.version>2.0</jsp.version>
        <jstl.version>1.2</jstl.version>
        <druid.version>1.1.10</druid.version>
    </properties>

    <!--版本托管:只定义版本,子模块按需引入,不会全部下载jar包-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>${mybatis.version}</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <!--子模块之间依赖:core模块坐标,war子模块引入该依赖即可拿到core里面所有类-->
            <dependency>
                <groupId>cn.tx.music</groupId>
                <artifactId>ham-core</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

重点区分:

<dependencies>:直接引入 jar,所有子模块全部继承,全部下载。

<dependencyManagement>:仅做版本声明,子模块需要手动写 dependency 才会真正引入,推荐聚合项目使用。

三、子模块 pom 编写

3.1 hami‑core(jar 公共模块)

packaging 默认 jar;通过<parent>继承父工程;直接写 dependencies 引入需要的包,不需要写 version,版本由父工程 dependencyManagement 管控。

复制代码
<?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/xsd/maven-4.0.0.xsd">
    <!--继承父工程-->
    <parent>
        <artifactId>ham-parent</artifactId>
        <groupId>cn.tx.music</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>ham-core</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
    </dependencies>
</project>

3.2 hami‑console 后台(war 模块)

打包方式设置war;引入 hami‑core 依赖,直接复用 core 中所有 model、service、dao 代码。

复制代码
<?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/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>ham-parent</artifactId>
        <groupId>cn.tx.music</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>ham-console</artifactId>
    <packaging>war</packaging>

    <dependencies>
        <!--依赖核心模块,拿到dao/service/model-->
        <dependency>
            <groupId>cn.tx.music</groupId>
            <artifactId>ham-core</artifactId>
        </dependency>
        <!--web相关依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>

hami‑portal、hami‑file 配置和 hami‑console 几乎一致,只需要修改 artifactId。

打包方式区分

pom:父聚合工程,用来管理版本、聚合子模块,不能部署 tomcat。

jar:普通 Java 包,hami‑core,给其他模块依赖,不能直接部署 tomcat。

war:web 工程,可以放到 tomcat 运行,包含 webapp、jsp、web.xml。

四、IDEA 环境配置(聚合项目重点)

4.1 JDK 配置

File → Project Structure

Project SDK:选择 JDK1.8

Project language level:8

4.2 Maven 配置

File → Settings → Build,Execution,Deployment → Build Tools → Maven

Maven home directory:本地解压好的 maven3.5.3 路径

User settings file:勾选 Override,指向自己本地仓库的 settings.xml

Working directory 运行工作目录

执行 hami‑core 下逆向工程、代码生成器 main 方法的时候,运行配置的Working directory必须设置为hami‑parent 父工程文件夹,否则读取 xml、tpl 模板文件报FileNotFoundException文件找不到。

现象:同样代码单模块正常,多模块报找不到配置文件,90% 都是工作目录没有指向父工程。

五、Maven 聚合项目开发流程

在 MySQL 执行 SQL 脚本,创建数据库 ham 以及所有数据表

编写 hami‑core 模块:实体 model、dao、mapper.xml、service、通用 BaseDao、BaseService,逆向工程、自定义代码生成器全部写在 core

先编译父工程:mvn clean install,把 hami‑core 安装到本地 maven 仓库

重要:war 模块依赖 hami‑core,必须 install 之后,war 模块才能识别 core 里面的 Java 类,否则报类找不到。

开发 hami‑console 后台:只写 Controller、jsp 页面,service 直接注入 core 中定义好的 Service

开发 hami‑portal 前台播放器模块,同样依赖 core

hami‑file 独立文件服务器配置 tomcat,处理图片、mp3 上传

分别部署 war 包到不同 tomcat,实现多服务运行。

六、高频踩坑汇总

坑 1:子模块找不到 hami‑core 里面的类

没有执行mvn clean install父工程,core 没有安装到本地仓库。

父、子模块 groupId、artifactId、version 版本号不一致。

core 模块编译报错,打包失败,install 不会生成可用 jar。

坑 2:执行 main 方法读取 xml/tpl 模板报 FileNotFoundException

原因:IDEA 运行配置 Working directory 不是父工程 ham‑parent。

解决:Edit Configurations → 修改 Working directory,选择父工程根目录。

坑 3:版本冲突,同一个 jar 出现多个版本

使用 Maven Helper 插件查看依赖树,排除冲突 jar;全部版本交给父工程dependencyManagement统一管控,子模块不写 version。

坑 4:war 模块 tomcat 启动,报 servlet-api 类重复

servlet-api scope 设置为provided,代表编译使用,tomcat 运行时由容器提供,不要打入 war 包。

复制代码
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <scope>provided</scope>
</dependency>

坑 5:父工程写 dependencies,所有子模块全部引入大量无用 jar

不要在父工程直接写<dependencies>,优先使用dependencyManagement做版本托管,子模块按需引入。

坑 6:聚合打包顺序异常

执行 mvn package 父工程,maven 会自动按照依赖顺序编译:先 core,再 console/portal/file。

如果手动打包,必须先打包 core。

七、聚合项目优点

公共业务(dao/service/model)只写一份,core 模块复用,减少重复代码;后台、前台业务层直接复用。

版本统一管理,修改版本号,只需要改父工程 properties,子模块无需改动。

业务解耦:后台、前台、文件服务器拆分成独立 war,可以分开部署,单独重启。

适合中型项目,课程大作业、初级企业项目常用架构。

相关推荐
Frank_refuel1 小时前
【C++八股】面向对象
开发语言·c++
青 春 记 忆1 小时前
零基础入门python20:Flask配置、扩展和蓝图拆分
python·flask·后端开发
m0_380743872 小时前
为 OpenAI 兼容接口配置教程
开发语言·python·node.js
万邦科技Lafite3 小时前
阿里巴巴拍立淘按图搜索商品API返回值实践:提升用户购物满意度的关键措施
开发语言·api·开放api·电商开放平台·京东开放平台
小小龙学IT4 小时前
Qt 6 跨平台开发完全指南:从信号槽机制到实际项目落地
开发语言·qt
leisoo80974 小时前
ig50数据落盘ClickHousevsTimescaleDBvsDuckDB实测对比 IG50免费开源股票数据API接口
开发语言·jvm·数据库·python·json
卷无止境4 小时前
FastAPI 的 Metadata 到底是什么,又牵动了哪些核心概念
后端·python
卷无止境4 小时前
FastAPI 调试实战,从断点到生产环境的排错心法
后端·python
敢敢のwings4 小时前
智元 GO-2 与 AgiBot-World 深度解读
开发语言·后端·golang