在企业级项目与微服务架构开发中,传统单体 Maven 项目普遍存在代码耦合度高、依赖版本混乱、构建效率低下、多人团队协作困难等痛点。Maven 模块化开发 依托聚合、继承、依赖管理三大核心机制,将大型项目拆分为若干职责单一、可独立构建、可复用解耦的子模块。
顶级父工程通过 <modules> 标签统一管理所有子模块,在父工程目录执行 Maven 命令时,Maven 自动根据模块依赖拓扑顺序,依次完成所有子模块的清理、编译、测试、打包、安装,实现全局一键构建。
所有子模块通过 <parent> 标签继承顶级父工程,统一复用项目编码、JDK 编译版本、基础坐标等通用配置,避免各模块重复编写冗余配置。
通过 dependencyManagement 结合 import 方式集中管控框架、中间件、第三方工具及自定义模块版本,仅声明版本不实际引入依赖;子模块引用依赖时无需指定版本,从根源杜绝版本冲突、版本不统一问题。
mall 顶级父工程(pom)
├── mall-dependencies # 全局依赖版本统一管理(pom)
├── mall-common # 公共工具通用模块(jar)
├── mall-system # 核心大业务模块(整合用户/订单等业务)(jar)
└── mall-admin # 项目唯一启动入口模块(jar)全局严格遵循层级命名
# 域名反转.项目名.模块名
com.lusifer.mall.common # 公共工具模块
com.lusifer.mall.system # 核心大业务模块
com.lusifer.mall.admin # 统一启动模块mall
顶级父工程,pom 打包;负责聚合所有子模块、定义全局属性、通过 import 导入 Spring Boot 及自定义依赖管理,不编写任何业务代码
mall-dependencies
依赖管理模块,pom 打包;集中统一管理所有第三方框架、工具类、自定义业务模块版本,是项目唯一版本定义入口
mall-common
公共工具模块,jar 打包;仅存放通用工具类、常量类,不包含任何业务实体与业务逻辑,供所有业务模块依赖复用
mall-system
核心大业务模块,jar 打包;整合用户、订单等全量业务,内部独立划分 entity / mapper / service / controller 分层,无独立启动类
mall-admin
统一启动模块,jar 打包;项目唯一启动入口,整合所有业务模块依赖,负责 Spring Boot 容器启动、全局配置、组件扫描加载
mall
<?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>com.lusifer</groupId>
<artifactId>mall</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<name>mall</name>
<!-- 聚合所有子模块 -->
<modules>
<module>mall-dependencies</module>
<module>mall-common</module>
<module>mall-system</module>
<module>mall-admin</module>
</modules>
<!-- 全局统一属性 -->
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.boot.version>3.5.13</spring.boot.version>
</properties>
<!-- 依赖管理:使用 import 统一导入版本规范 -->
<dependencyManagement>
<dependencies>
<!-- 导入 Spring Boot 官方版本管理 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 导入自定义项目依赖管理模块 -->
<dependency>
<groupId>com.lusifer</groupId>
<artifactId>mall-dependencies</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>17</source>
<target>17</target>
<parameters>true</parameters>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>mall-dependencies
<?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>com.lusifer</groupId>
<artifactId>mall-dependencies</artifactId>
<version>1.0.0</version>
<name>mall-dependencies</name>
<packaging>pom</packaging>
<properties>
<lombok.version>1.18.32</lombok.version>
</properties>
<!-- 统一声明所有依赖版本,子模块直接引用无需写版本 -->
<dependencyManagement>
<dependencies>
<!-- 第三方工具依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<!-- 自定义子模块版本声明 -->
<dependency>
<groupId>com.lusifer</groupId>
<artifactId>mall-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.lusifer</groupId>
<artifactId>mall-system</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>mall-common
仅提供通用工具类,无业务实体、无业务逻辑。
<?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>
<groupId>com.lusifer</groupId>
<artifactId>mall</artifactId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>mall-common</artifactId>
<name>mall-common</name>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>工具类代码
// 字符串工具类
package com.lusifer.mall.common.util;
public class StringUtils {
public static boolean isEmpty(String str) {
return str == null || str.trim().isEmpty();
}
public static boolean isNotEmpty(String str) {
return !isEmpty(str);
}
}// 日期工具类
package com.lusifer.mall.common.util;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class DateUtils {
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
public static String getNowTime() {
return LocalDateTime.now().format(FORMATTER);
}
}mall-system
整合用户、订单全量业务,纯业务模块,无启动类,内部独立分层。
<?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>
<groupId>com.lusifer</groupId>
<artifactId>mall</artifactId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>mall-system</artifactId>
<name>mall-system</name>
<dependencies>
<dependency>
<groupId>com.lusifer</groupId>
<artifactId>mall-common</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>用户实体类
package com.lusifer.mall.system.entity;
import lombok.Data;
import java.io.Serializable;
@Data
public class User implements Serializable {
private Long userId;
private String username;
private Integer age;
}用户数据层
package com.lusifer.mall.system.mapper;
import com.lusifer.mall.system.entity.User;
import org.springframework.stereotype.Repository;
@Repository
public class UserMapper {
public User selectById(Long userId) {
User user = new User();
user.setUserId(userId);
user.setUsername("lusifer-mall-user");
user.setAge(20);
return user;
}
}用户业务层
package com.lusifer.mall.system.service;
import com.lusifer.mall.system.entity.User;
import com.lusifer.mall.system.mapper.UserMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class UserService {
private final UserMapper userMapper;
public User getUserById(Long userId) {
return userMapper.selectById(userId);
}
}用户控制层
package com.lusifer.mall.system.controller;
import com.lusifer.mall.system.entity.User;
import com.lusifer.mall.system.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@GetMapping("/{id}")
public User getUserInfo(@PathVariable Long id) {
return userService.getUserById(id);
}
}订单实体类
package com.lusifer.mall.system.entity;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
public class Order {
private Long orderId;
private Long userId;
private BigDecimal orderPrice;
private LocalDateTime createTime;
}订单数据层
package com.lusifer.mall.system.mapper;
import com.lusifer.mall.system.entity.Order;
import org.springframework.stereotype.Repository;
@Repository
public class OrderMapper {
public void insertOrder(Order order) {
System.out.println("订单入库完成:" + order);
}
}订单业务层
package com.lusifer.mall.system.service;
import com.lusifer.mall.system.entity.Order;
import com.lusifer.mall.system.entity.User;
import com.lusifer.mall.system.mapper.OrderMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Service
@RequiredArgsConstructor
public class OrderService {
private final UserService userService;
private final OrderMapper orderMapper;
public Order createOrder(Long orderId, Long userId) {
// 调用模块内用户服务
User user = userService.getUserById(userId);
Order order = new Order();
order.setOrderId(orderId);
order.setUserId(userId);
order.setOrderPrice(new BigDecimal("199.00"));
order.setCreateTime(LocalDateTime.now());
orderMapper.insertOrder(order);
return order;
}
}订单控制层
package com.lusifer.mall.system.controller;
import com.lusifer.mall.system.entity.Order;
import com.lusifer.mall.system.service.OrderService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/order")
@RequiredArgsConstructor
public class OrderController {
private final OrderService orderService;
@PostMapping("/create")
public Order createOrder(@RequestParam Long orderId, @RequestParam Long userId) {
return orderService.createOrder(orderId, userId);
}
}mall-admin
项目唯一启动入口,整合核心业务模块
<?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>
<groupId>com.lusifer</groupId>
<artifactId>mall</artifactId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>mall-admin</artifactId>
<name>mall-admin</name>
<dependencies>
<!-- 依赖核心业务模块 -->
<dependency>
<groupId>com.lusifer</groupId>
<artifactId>mall-common</artifactId>
</dependency>
<dependency>
<groupId>com.lusifer</groupId>
<artifactId>mall-system</artifactId>
</dependency>
<!-- Spring Boot 核心依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>启动类
package com.lusifer.mall.admin;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan(basePackages = "com.lusifer.mall")
public class MallAdminApplication {
public static void main(String[] args) {
SpringApplication.run(MallAdminApplication.class, args);
}
}配置文件
server:
port: 8080
spring:
application:
name: mall-admin在顶级父工程 mall 根目录执行:
mvn clean install仅启动 mall-admin 模块下 MallAdminApplication;
访问用户接口 (GET):http://localhost:8080/user/1;
访问订单接口 (POST):http://localhost:8080/order/create?orderId=1001&userId=1;
业务模块内的跨业务调用、Spring 容器扫描加载均正常。
顶级父工程、依赖管理模块统一使用 pom 打包,仅做配置与聚合,禁止编写业务代码;
严格遵循 域名反转. 项目名. 模块名 包名规范,统一项目层级结构;
mall-common 只存放通用工具类、常量类,禁止存放业务实体与业务逻辑;
mall-system 大业务模块仅作为依赖 Jar 包,禁止自定义启动类,统一由 mall-admin 启动;
所有版本统一在 mall-dependencies 中管控,业务模块引入依赖不允许指定版本号;
模块间遵循单向依赖,禁止循环依赖,依赖顺序:common → system → admin;
必须在 mall 根目录执行构建,保证 Maven 按拓扑顺序编译、打包、安装。
单一职责:每个模块职责完全隔离:父工程负责聚合、dependencies 负责版本管理、common 负责通用工具、system 负责全量核心业务、admin 负责容器启动;业务内部按领域、分层各司其职
开闭原则:新增业务功能时,无需修改现有工程配置与代码,仅在 mall-system 内扩展对应代码即可,对扩展开放、对原有代码修改关闭
依赖倒置:业务模块不依赖具体框架版本与底层实现,而是依赖统一版本管理规范与通用公共能力,底层版本升级不影响上层业务代码
迪米特法则:模块之间仅通过 Maven 依赖弱关联,内部实现细节对外隐藏;业务模块只依赖必需的公共模块,不感知无关模块内部结构
组合聚合:通过 Maven 模块依赖组合、Spring 构造器注入组合复用现有能力,而非通过类继承实现复用,有效降低耦合度