Skip to content

请求链路

本文说明从用户登录到业务 SQL 执行的完整请求链路,帮助你理解系统各层之间的协作方式。

完整请求链路

浏览器(Vue 3 SPA)
  │  POST /auth/login {"username":"admin","password":"123456"}

Nginx(生产环境)/ Vite Proxy(开发环境)
  │  路由转发 → localhost:8580

Controller 层
  │  @RestController → 参数校验 → 协议转换

Service 层
  │  业务编排 → 事务管理 → 调用 Mapper

Mapper 层(MyBatis-Plus + XML)
  │  SQL 执行 → 结果映射 → 返回 Entity

MySQL 8.0
  │  查询 sys_user 表

各层处理详情

1. 前端发起请求

javascript
// Vue 组件或 composable 中
import { request } from '@/utils/http'

const login = async () => {
  const res = await request.post('/auth/login', {
    username: 'admin',
    password: '123456'
  })
  // 服务端返回: { code: 200, data: { token: "xxx" }, msg: "success" }
}

2. 请求经过拦截器链

Request 进入 →
  Undertow 容器接收
  → Filter 链
  → SaTokenInterceptor(认证拦截,白名单放行登录接口)
  → TenantLineInnerInterceptor(租户拦截,自动追加 WHERE tenant_id = ?)
  → DataScopeInterceptor(数据权限拦截,按规则改写 SQL)
  → Controller

3. Controller 层

java
@RestController
public class AuthController {

    @PostMapping("/auth/login")
    public RespInfo login(@Valid @RequestBody LoginDto dto) {
        // 参数校验、协议转换
        String token = authService.login(dto);
        return RespInfo.success(token);
    }
}

4. Service 层

java
@Service
public class AuthServiceImpl implements AuthService {

    public String login(LoginDto dto) {
        // 业务编排:验证密码、生成 Token、记录日志
        SysUser user = userMapper.selectOne(
            new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUsername, dto.getUsername())
        );
        // 密码验证、Token 生成...
    }
}

5. Mapper 层

java
@Mapper
public interface SysUserMapper extends BaseMapper<SysUser> {
    // 继承 MyBatis-Plus BaseMapper,获得基础 CRUD 能力
    // 复杂查询写在 XML 中
}

6. 统一响应

所有接口返回 RespInfo 格式:

json
{
  "code": 200,
  "data": { "token": "xxx" },
  "msg": "success"
}

关键中间件

组件位置作用
Sa-TokenFilter 层认证鉴权、Session 管理
租户拦截器MyBatis 拦截器自动追加租户条件
数据权限拦截器MyBatis 拦截器XML SQL 改写
RedisService 层缓存 Token、分布式锁
Flyway启动阶段数据库版本迁移

Forge Admin — 基于 Vue3 + Spring Boot 的企业级后台管理框架