`api`、`common`、`service`、`web` 分层架构设计

分层架构设计apicommonserviceweb 是现代 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 模块)

示例:

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 请求 ,接收参数、调用 serviceapi,返回 JSON,依赖:api + common, 对外暴露 HTTP 接口。
  • 包含内容:
    • Controller:UserController, OrderController
    • 接收 @RequestParam, @RequestBody
    • 参数校验(@Valid
    • 调用 serviceapi 客户端
    • 返回 ResponseResult<T>

示例:

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 依赖 apicommon
  • 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 ❌ 应通过 serviceapi
service 返回 ResponseResult service 只返回业务对象,web 层封装响应
api 包含实现类 api 只定义接口,不写实现

7、变体设计(根据项目规模调整)

项目规模 推荐结构
小型项目 单模块:controllerservicecommon 在同一个项目
中型项目 四模块:commonserviceapiweb
大型微服务 每个服务独立部署,api 模块单独发布为 SDK

总结

模块 职责 依赖谁 被谁依赖
common 工具、异常、常量 所有模块
service 业务逻辑 common web、其他服务
api 接口定义(RPC/远程调用) common web、其他服务
web HTTP 接口(Controller) api + common 客户端(前端、App)
相关推荐
iCoding9136 分钟前
前端分页 vs 后端分页:技术选型
前端·后端·系统架构
王中阳Go背后的男人42 分钟前
我发现不管是Java还是Golang,懂AI之后,是真吃香!
后端
焰火199944 分钟前
[Java]基于Redis的分布式环境下的自增编号生成器
java·后端
用户68545375977691 小时前
SQL优化完全指南:让你的数据库从"蜗牛"变"猎豹"!🐌➡️🐆
后端
大巨头1 小时前
豆包帮忙梳理知识点,真强大!
后端
ZhengEnCi1 小时前
JPA-SQL 语句使用完全指南-自动生成vs手动编写的智能选择策略
java·spring boot·sql
疯狂的程序猴1 小时前
Vue前端开发工具大全,从编码到调试的高效工作流指南
后端
渣哥1 小时前
别再乱用了!Spring AOP 与 AspectJ 的区别比你想的复杂
javascript·后端·面试
毕设源码-钟学长1 小时前
【开题答辩全过程】以 菜谱分享平台为例,包含答辩的问题和答案
java·eclipse
hui函数1 小时前
Python全栈(基础篇)——Day10:后端内容(map+reduce+filter+sorted+实战演示+每日一题)
后端·python