分层架构设计 :api
、common
、service
、web
是现代 Java 项目(尤其是基于 Spring Boot)中最常见的模块划分。
1、整体架构图(典型 Maven 多模块项目)
project-root
├── common ← 公共模块
├── service ← 业务逻辑模块
├── api ← 对外 API 模块
└── web ← Web 接口层(或 UI 层)
这是一种 "分层 + 模块化" 的设计,常见于微服务或大型单体应用。
2、各模块职责
2.1. common
模块(公共模块)
-
存放跨模块共享的代码,避免重复,被其他所有模块依赖。
-
包含内容:
- 工具类:
DateUtils
,StringUtils
,JsonUtils
- 公共异常:
BusinessException
,GlobalException
- 统一返回格式:
ResponseResult<T>
、ErrorCode
- 常量类:
Constants
,StatusEnum
- 基础配置:
BaseConfig
,RedisTemplate
配置 - 分页封装:
PageResult<T>
- 工具类:
示例:
arduino
// 统一响应格式
public class ResponseResult<T> {
private int code;
private String message;
private T data;
// getter/setter
}
2.2 service
模块(业务逻辑层)
-
实现核心业务逻辑 ,依赖:
common
+mapper
(或repository
)。 -
包含内容:
- Service 接口和实现类:
UserService
,OrderService
- 业务逻辑:事务控制、流程编排、规则判断
- 调用
common
模块的工具和异常 - 调用
dao
/mapper
(数据访问层,有时独立为repository
模块)
- Service 接口和实现类:
示例:
typescript
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public User findById(Long id) {
return userMapper.selectById(id);
}
@Transactional
public void transferMoney(Long from, Long to, BigDecimal amount) {
}
}
2.3. api
模块(接口定义层)
- 对外暴露的服务接口 (通常是接口类,不含实现),用于模块间解耦 或RPC 调用 ,依赖:
common
,被web
和其他服务模块依赖。 - 包含内容:
- 接口定义:
UserServiceApi
,OrderServiceApi
- DTO(数据传输对象):
UserDTO
,OrderDTO
- RPC 调用参数和返回值
- 接口定义:
示例:
java
// 定义一个远程可调用的接口
public interface UserServiceApi {
ResponseResult<UserDTO> getUserById(Long id);
ResponseResult<List<UserDTO>> listUsers(PageQuery query);
}
使用场景:
- 微服务之间通过 Dubbo、gRPC 调用
web
模块依赖api
,面向接口编程- 前后端分离时,
api
模块也可生成 OpenAPI 文档
2.4. web
模块(Web 接口层)
- 处理 HTTP 请求 ,接收参数、调用
service
或api
,返回 JSON,依赖:api
+common
, 对外暴露 HTTP 接口。 - 包含内容:
- Controller:
UserController
,OrderController
- 接收
@RequestParam
,@RequestBody
- 参数校验(
@Valid
) - 调用
service
或api
客户端 - 返回
ResponseResult<T>
- Controller:
示例:
less
@RestController
@RequestMapping("/api/user")
public class UserController {
@Autowired
private UserService userService; // 或 UserServiceApi
@GetMapping("/{id}")
public ResponseResult<UserDTO> getUser(@PathVariable Long id) {
User user = userService.findById(id);
return ResponseResult.success(UserConverter.toDTO(user));
}
}
3、依赖原则
markdown
web → api → common
↘
service → common
web
依赖api
和common
service
依赖common
api
依赖common
common
不依赖任何模块(否则会循环依赖!)
原则:
依赖只能向"上"或"同级",不能"向下"
common
是最底层,web
是最上层。
4、父pom文件(Maven 多模块)
xml
<!-- 父 pom.xml -->
<modules>
<module>common</module>
<module>service</module>
<module>api</module>
<module>web</module>
</modules>
每个模块都是一个独立的 Maven 项目:
common/pom.xml
service/pom.xml
api/pom.xml
web/pom.xml
5、设计优势
优势 | 说明 |
---|---|
解耦清晰 | 各层职责分明,便于维护 |
复用性强 | common 被所有模块共享 |
便于测试 | 可独立测试 service 逻辑 |
支持微服务 | api 模块可用于服务间调用 |
团队协作 | 不同团队负责不同模块 |
6、常见错误
错误 | 正确做法 |
---|---|
common 依赖 service |
❌ common 不能依赖任何业务模块 |
web 直接访问 mapper |
❌ 应通过 service 或 api |
service 返回 ResponseResult |
❌ service 只返回业务对象,web 层封装响应 |
api 包含实现类 |
❌ api 只定义接口,不写实现 |
7、变体设计(根据项目规模调整)
项目规模 | 推荐结构 |
---|---|
小型项目 | 单模块:controller 、service 、common 在同一个项目 |
中型项目 | 四模块:common 、service 、api 、web |
大型微服务 | 每个服务独立部署,api 模块单独发布为 SDK |
总结
模块 | 职责 | 依赖谁 | 被谁依赖 |
---|---|---|---|
common |
工具、异常、常量 | 无 | 所有模块 |
service |
业务逻辑 | common |
web 、其他服务 |
api |
接口定义(RPC/远程调用) | common |
web 、其他服务 |
web |
HTTP 接口(Controller) | api + common |
客户端(前端、App) |