请求链路
本文说明从用户登录到业务 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)
→ Controller3. 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-Token | Filter 层 | 认证鉴权、Session 管理 |
| 租户拦截器 | MyBatis 拦截器 | 自动追加租户条件 |
| 数据权限拦截器 | MyBatis 拦截器 | XML SQL 改写 |
| Redis | Service 层 | 缓存 Token、分布式锁 |
| Flyway | 启动阶段 | 数据库版本迁移 |
