Files
apes-Authon-history/docs/代码深度解析与分析过程.md
T
figmar 9cbb1f7695 init: apes-Authon-history — 剥离历史与源码分析归档
- docs/: 源码分析报告、代码深度解析、项目说明书、独立服务化方案
- backend/: 账权模块提取说明(提取原则、文件清单、耦合度验证)
- frontend/: 前端剥离方案、剥离历史与说明、框架修改详情
2026-08-09 13:04:04 +08:00

27 KiB
Raw Blame History

代码深度解析与分析过程

本文档记录了对账权平台(原掌渠 SaaS 云平台)前后端源码的完整深度分析过程,包括项目结构剖析、账权模块耦合度量化、设计意图逆向还原、以及独立服务化可行性论证。内容来自实际的代码走查,非概要性总结。


目录

  1. 后端项目深度分析
  2. 前端项目深度分析
  3. 账权模块深度代码走查
  4. 耦合度量化分析
  5. 设计意图逆向分析——六大障碍的出发点与判定
  6. 独立服务化可行性论证

1. 后端项目深度分析

1.1 基本信息

项目
包根 cn.apes.cloud
启动类 cn.apes.CloudApplication
框架 Spring Boot 2.2.1 + Java 11
ORM MyBatis Plus 3.5.7
动态数据源 dynamic-datasource 3.6.1
缓存/分布式 Redisson 3.35.0
认证框架 cn.apes:apes-commons:0.0.7-SNAPSHOT(外部 JAR
AI 集成 OpenAI SDK + Groovy 脚本引擎

1.2 包结构总览

cn.apes.cloud
├── CloudApplication.java              # 启动类
├── config/                             # 配置类
│   ├── DataSourceHeaderAspect.java     # 动态数据源切面(@Order(1)
│   ├── MybatisPlusConfig.java          # 分页插件
│   ├── RedisConfig.java               # Redisson 配置
│   ├── TenantSource.java              # 多租户数据源注解
│   └── WebMvcConfig.java              # 跨域 + 拦截器
├── filter/
│   └── AccessTokenFilter.java          # AccessToken 开放平台认证过滤器
├── controller/                         # 62 个 Controller
│   ├── UserInfoController.java         # 用户管理
│   ├── PermissionController.java       # 权限管理
│   ├── CustomerInfoController.java     # 企业/租户管理
│   ├── SysRoleController.java          # 角色管理
│   ├── SysMenuController.java         # 菜单管理
│   ├── SysDeptController.java         # 部门管理
│   ├── SysAccessTokenController.java  # AccessToken 管理
│   ├── LoginController.java           # 登录/SSO
│   ├── TraceProductController.java     # 溯源产品
│   ├── Weight*Controller.java          # 过磅系列
│   ├── Agent*Controller.java           # AI Agent 系列(10+
│   └── ...                             # 其余业务 Controller
├── service/                            # Service 接口
│   └── impl/                           # Service 实现
├── mapper/                             # MyBatis Mapper 接口
├── domain/
│   └── entity/                         # 数据实体
├── util/
│   ├── OperationLogUtil.java           # 操作日志工具(静态封装)
│   └── ...
├── aspect/                             # AOP 切面
└── job/                                # 定时任务

1.3 核心配置分析

多数据源配置application.yml):

spring:
  datasource:
    dynamic:
      datasource:
        cloud:    # 主库 — 账权、用户、企业
        user:     # 用户业务库
        huoban:    # 伙伴云集成库
        plant:    # 农业种植库
        zx:       # 其他业务库

数据源切换通过 @TenantSource 注解 + DataSourceHeaderAspect@Order(1))实现:

  • 切面拦截标注了 @TenantSource 的类/方法
  • 从 HTTP Header X-Tenant-ID 读取目标数据源
  • 调用 DynamicDataSourceContextHolder.push(head) 切换
  • 切面执行前先调用 AuthContext.clean() 清理 ThreadLocal(防串号),除非 AccessTokenFilter 已标记 accessTokenVerified

1.4 Controller 分类

类别 数量 代表 Controller
账权类 8 UserInfo, Permission, SysRole, SysMenu, SysDept, CustomerInfo, SysAccessToken, Login
溯源类 ~6 TraceProduct, TraceBatch, TraceCode, TraceLink, TraceRecord, TraceConfig
过磅类 ~5 WeightTicket, WeightDevice, WeightReport, WeightConfig, WeightPrint
AI Agent 类 ~10 AgentChat, AgentTool, AgentKnowledge, AgentModel, AgentPrompt, AgentFlow, AgentDatasource, AgentFile, AgentFunction, AgentSession
农业类 ~8 Crop, Farm, Field, Sensor, Device, Irrigation, Pest, Weather
其他业务 ~25 套餐、订单、支付、统计、文件、消息、日志等

1.5 核心业务实体

用户/认证域:
  UserInfo          # 用户
  CustomerInfo      # 企业/租户
  SysRole           # 角色
  SysMenu           # 菜单
  SysDept           # 部门
  SysAccessToken    # 开放平台令牌
  SysPermission     # 权限项
  SysSsoConfig      # SSO 配置

溯源域:
  TraceProduct      # 溯源产品
  TraceBatch        # 批次
  TraceCode         # 溯源码
  TraceLink         # 追溯链路
  TraceRecord       # 操作记录

过磅域:
  WeightTicket      # 过磅单
  WeightDevice      # 地磅设备

AI Agent 域:
  AgentModel        # 模型配置
  AgentPrompt       # 提示词模板
  AgentTool         # 工具定义
  AgentSession      # 会话
  AgentKnowledge    # 知识库

1.6 定时任务

@Component
public class XxlJobHandler {
    @XxlJob("cleanExpiredTokens")    // 清理过期 AccessToken
    @XxlJob("syncTraceData")         // 同步溯源数据
    @XxlJob("reportWeightStats")     # 过磅统计上报
}

1.7 LLM / AI Agent 平台

项目内置完整的 AI Agent 平台,核心能力包括:

  • Function CallingAgent 可以调用注册的 Java 方法作为工具
  • Groovy 动态工具:通过 Groovy 脚本引擎动态编译执行自定义工具逻辑,无需重启服务
  • 多轮对话管理AgentSession 管理上下文窗口
  • 知识库检索AgentKnowledge 支持向量检索(集成 Embedding)
  • ASR 语音识别:语音输入转文本
  • 多模型支持AgentModel 可配置 OpenAI/通义千问等
  • 工作流编排AgentFlow 支持节点式编排
  • 数据源接入AgentDatasource 连接外部数据库供 Agent 查询
  • 文件理解AgentFile 支持文档解析
  • 提示词模板AgentPrompt 管理系统提示词

2. 前端项目深度分析

2.1 基本信息

项目
框架 Vue 2.7.16
UI 库 Element UI 2.15.14
状态管理 Vuex 3.6.2
路由 Vue Router 3.6.5(动态路由)
HTTP Axios 0.21.4
构建 Vue CLI 5.0.8

2.2 目录结构

src/
├── main.js                # 入口:Element UI、全局组件注册
├── App.vue
├── permission.js          # 路由守卫:动态权限路由
├── router/                # 静态路由 + 动态路由加载
├── api/                   # API 接口模块(按业务域分文件)
├── views/                 # 页面组件(85+
├── components/            # 公共组件
├── layout/                # 布局框架
│   └── components/
│       ├── Sidebar/       # 侧边栏(动态菜单)
│       ├── Navbar/        # 顶栏
│       └── AppMain/       # 主内容区
├── store/                 # Vuex
│   └── modules/
│       ├── user.js        # 用户状态
│       ├── permission.js  # 权限路由
│       └── ...
├── utils/                 # 工具函数
│   ├── request.js         # Axios 封装(拦截器)
│   ├── auth.js            # Token 管理
│   ├── constUtil.js       # 常量
│   └── get-page-title.js  # 页面标题
├── config/                # 配置
│   └── tracingOpenKey.js  # 溯源开放密钥
├── styles/                # 全局样式
└── assets/                # 静态资源

2.3 动态路由系统

路由分为静态路由和动态路由:

  • 静态路由:登录页、404 页、无权限页面
  • 动态路由:通过后端 API GET /system/menu/routes 获取,按角色权限动态注册

路由元信息 meta 包含 menuType 字段,区分 4 种类型:

  • menu — 侧边栏菜单
  • button — 按钮级权限
  • link — 外链
  • hidden — 隐藏路由

2.4 前端 API 代理配置(vue.config.js

module.exports = {
  devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost:8080',
        changeOrigin: true,
        pathRewrite: { '^/api': '' }
      }
    }
  },
  configureWebpack: {
    name: '账权平台'
  }
}

2.5 Vuex 状态管理

Module 职责
user Token 存储/清除、用户信息获取、登录/登出
permission 动态路由生成、菜单树构建
settings 侧边栏折叠、主题等 UI 状态

2.6 前端 AI 相关页面

前端包含完整的 AI Agent 管理界面:

  • views/agent/chat — 对话界面
  • views/agent/model — 模型配置
  • views/agent/prompt — 提示词管理
  • views/agent/tool — 工具管理(支持 Groovy 脚本编辑)
  • views/agent/knowledge — 知识库管理
  • views/agent/flow — 工作流编排
  • views/agent/session — 会话管理
  • views/agent/datasource — 数据源管理
  • views/agent/file — 文件管理
  • views/agent/function — 函数管理

3. 账权模块深度代码走查

3.1 认证流程

整个认证流程涉及三个层次:

请求进入 → AccessTokenFilter(开放平台令牌)
         → DataSourceHeaderAspect(清理 ThreadLocal + 切数据源)
         → LoginAspectapes-commons 中,@Login AOP 填充 AuthContext
         → Controller 方法执行

3.1.1 AccessTokenFilter(开放平台认证)

// 文件:cn.apes.cloud.filter.AccessTokenFilter
// 职责:为外部系统提供免登录的 API 访问

// 1. 从 Header 提取 TokenX-Access-Token 或 Authorization: Bearer
// 2. 调用 SysAccessTokenService.validate() 校验
// 3. 校验通过 → 将用户/企业信息写入 Redis(模拟登录态)
//    - key = token → JSONObject {id:0, nickName:"AccessToken:xxx"}
//    - key = token:customer → 企业信息 JSON
// 4. 包装 request,注入 "token" header → 让后续 @Login AOP 能取到
// 5. 标记 request.setAttribute("accessTokenVerified", true)
//    → DataSourceHeaderAspect 检测到此标记则跳过 AuthContext.clean()

关键代码片段:

// 写入 Redis 模拟登录态
RBucket<JSONObject> userBucket = redissonClient.getBucket(redisToken);
userBucket.set(userObj, 1, TimeUnit.DAYS);

RBucket<JSONObject> customerBucket = redissonClient.getBucket(redisToken + ":customer");
customerBucket.set(customerObj, 1, TimeUnit.DAYS);

// 标记已验证
request.setAttribute("accessTokenVerified", true);

3.1.2 DataSourceHeaderAspect(数据源切换 + ThreadLocal 清理)

// 文件:cn.apes.cloud.config.DataSourceHeaderAspect
// @Order(1) — 在 LoginAspect 之前执行

@Around("@within(tenantSource) || @annotation(tenantSource)")
public Object exc(ProceedingJoinPoint pjp, TenantSource tenantSource) throws Throwable {
    HttpServletRequest request = ...;
    
    // 如果 AccessToken 过滤器已验证,保留其设置的认证上下文
    if (request.getAttribute("accessTokenVerified") == null) {
        AuthContext.clean();  // 清理上一请求残留的 ThreadLocal
    }
    
    String head = request.getHeader("X-Tenant-ID");
    if (StrUtil.isEmpty(head)) head = "user";  // 默认数据源
    
    DynamicDataSourceContextHolder.push(head);  // 切换数据源
    return pjp.proceed();
}

3.1.3 LoginAspectapes-commons 内部,不可见源码)

根据 pom.xml 中的 apes-commons:0.0.7-SNAPSHOT 依赖,推断其行为:

  • 拦截标注 @Login 的 Controller 类/方法
  • request.getHeader("token") 获取 Token
  • 从 Redis 读取 RBucket<JSONObject>(token)RBucket<JSONObject>(token:customer)
  • 填充 AuthContext 的 ThreadLocalLoginUser + LoginCustomer

3.2 RBAC 权限模型

UserInfo (用户)
  └── SysUserCustomer (用户-租户关联,支持一人多租户)
        └── CustomerInfo (租户/企业)
              └── SysRole (角色)
                    └── SysMenu (菜单/权限项)
                          └── 权限标识 (permission key)

SysUserCustomer ←→ SysRole (用户-角色关联表)
SysRole ←→ SysMenu (角色-菜单关联表)

权限校验方式:PermissionServiceImpl 中实现按钮级权限检查,通过菜单的 permission 字段匹配。

3.3 多租户数据隔离

方式:共享数据库 + 动态数据源路由(非共享表 + tenant_id 模式)

所有请求 → DataSourceHeaderAspect → 读取 X-Tenant-ID Header → 切换数据源
                                                    ↓
                                           cloud / user / huoban / plant / zx

业务表通过 customer_id 字段关联 CustomerInfo不是物理外键,而是逻辑关联。

3.4 AuthContext 使用模式

AuthContext 来自 apes-commons,是 ThreadLocal 封装:

// 典型使用方式(出现在 52 个文件中)
AuthContext.getLoginInfo().getCustomer().getId()    // 当前租户 ID
AuthContext.getLoginInfo().getUser().getId()         // 当前用户 ID
AuthContext.getLoginInfo().getUser().getNickName()   // 当前用户名

配合 @Login 注解,业务 Controller 可以零感知地获取登录态:

@Login
@RestController
@RequestMapping("/tracking/config")
public class TrackingConfigController {
    
    @GetMapping("/list")
    public R list() {
        Long customerId = AuthContext.getLoginInfo().getCustomer().getId();
        // 直接使用,无需传参
        return R.ok(configService.listByCustomerId(customerId));
    }
}

3.5 OperationLogUtil 静态封装

// 文件:cn.apes.cloud.util.OperationLogUtil

@Component
public class OperationLogUtil {
    private static SysOperationLogService logService;
    private static RedissonClient redissonClient;
    
    @PostConstruct
    public void init() {
        logService = SpringContextHolder.getBean(SysOperationLogService.class);
        redissonClient = SpringContextHolder.getBean(RedissonClient.class);
    }
    
    public static void log(String module, String action, String desc) {
        // 从 AuthContext 自动获取操作人信息
        LoginInfo info = AuthContext.getLoginInfo();
        Long userId = info.getUser().getId();
        Long customerId = info.getCustomer().getId();
        // ... 记录日志
    }
}

11 个业务文件直接调用 OperationLogUtil.log(...),一行式 API,内部依赖 AuthContext

3.6 账权 Service 间内部调用

LoginController
  → UserInfoService.login()       # 登录验证
    → PermissionService.getUserPermissions()  # 获取权限
      → SysMenuService.getMenuTree()          # 菜单树
    → CustomerInfoService.getById()           # 企业信息

SysAccessTokenService.validate()
  → CustomerInfoServiceImpl.getById()         # 查企业信息
  → 写 Redis 模拟登录态

PermissionServiceImpl
  → UserInfoService.getUserById()             # 查用户
  → SysRoleService.getRolesByUserId()        # 查角色

约 8 处内部调用,全部在账权域内。


4. 耦合度量化分析

通过 grep 对源码树的精确统计:

4.1 AuthContext 引用统计

$ grep -rl "AuthContext" service-master/src/ | wc -l
52 个文件

$ grep -r "AuthContext" service-master/src/ | wc -l  
111 处引用

文件分布

  • Controller 层:~25 个文件(通过 @Login + AuthContext.getLoginInfo() 获取登录态)
  • Service 实现层:~15 个文件(业务逻辑中获取 customerId
  • 工具类/切面:~5 个文件(OperationLogUtilDataSourceHeaderAspect 等)
  • 配置/过滤器:~7 个文件(AccessTokenFilter 等)

4.2 OperationLogUtil 引用统计

$ grep -rl "OperationLogUtil" service-master/src/ | wc -l
11 个文件

调用方包括:AccessTokenFilter、各种 *Controller*ServiceImpl

4.3 账权 Service 被业务模块直接引用统计

$ grep -rl "import cn.apes.cloud.service.PermissionService\|import cn.apes.cloud.service.UserInfoService\|import cn.apes.cloud.service.CustomerInfoService\|import cn.apes.cloud.service.CustomerUserService\|import cn.apes.cloud.service.SysAccessTokenService" \
  service-master/src/main/java/cn/apes/cloud/service/impl/Trace*.java \
  service-master/src/main/java/cn/apes/cloud/service/impl/Weight*.java

# 结果:0 个匹配

关键发现:业务模块(Trace*、Weight*)不直接 import 账权 Service。它们仅通过 AuthContext(来自 apes-commons)间接获取登录态,不存在代码层面的直接依赖。

4.4 账权 Service 间内部调用统计

$ grep -rl "import cn.apes.cloud.service.impl.\|import cn.apes.cloud.service\." \
  service-master/src/main/java/cn/apes/cloud/service/impl/PermissionServiceImpl.java \
  service-master/src/main/java/cn/apes/cloud/service/impl/UserInfoServiceImpl.java

# 约 8 处交叉引用,全部在账权域内部

4.5 耦合度总结

指标 数值 解耦难度
AuthContext 引用文件 52 个 / 111 处 低(import 替换即可)
OperationLogUtil 引用 11 个文件 低(方法签名不变)
业务 Service → 账权 Service 直接调用 0 无需改造
账权 Service 间内部调用 ~8 处 随账权服务整体迁移
数据库外键约束 无(逻辑关联) 拆库时无需处理物理约束

5. 设计意图逆向分析——六大障碍的出发点与判定

判断标尺

分析这些障碍,要区分两件事:

  • 设计思路对不对(出发点是否站得住)
  • 当前形态能不能进微服务(实体要不要拆)

很多障碍属于"思路对、形态错"——不必推倒重来,只需"搬家 + 换填充源"。

障碍 ① AuthContextThreadLocal + Redis 会话)

设计出发点

  • 单体里最省事的"隐式传参":任何方法随时 AuthContext.getLoginInfo().getCustomer().getId() 拿当前租户,不用在每层方法签名里塞 customerId
  • Redis 做后端存储(key=token → user JSONkey=token:customer → 企业 JSON),会话可跨实例共享 → 单体水平扩容不用粘会话
  • @Login AOP 自动填充,业务零感知

评价:单体时代的经典正确做法。问题不在 ThreadLocal 本身,而在它不跨进程传播

判定 说明
保留 ThreadLocal 作为"服务内本地上下文"的机制——任何服务内部用 ThreadLocal 存当前用户都是对的
🔧 改造 填充来源(从"自己查 Redis"改"网关注入 Header")+ 跨服务传播方式。机制保留,来源替换,业务代码几无改动

障碍 ② apes-commons 黑盒(外部 0.0.7-SNAPSHOT JAR

设计出发点

  • 多项目共享基础框架:cn.apes:apes-commons 不止当前 service 在用,伙伴云/交易平台等多条产品线共用同一套认证
  • 把脏活(RSA 解密、Token 生成、Redis 读写、ThreadLocal 管理、@Login/LoginAspect)封进 JAR,各服务鉴权行为一致
  • pom.xml 里特意 exclude 了 hutool(避免版本冲突)——说明它确实被当"公共底座"对待

评价:平台化思路完全正确。黑盒不是罪,问题是要改它、又改不了。

判定 说明
保留 "共享基础库"这个思路 → 直接进化为自有 auth-sdk
🔧 改造 所有权收归自己(从外部 SNAPSHOT 依赖变成自维护 SDK),并用 Maven shade relocation 兼容旧包名,避免 52 个文件全量改 import

障碍 ③ OperationLogUtil 静态依赖

设计出发点

  • 极致调用便利:任何地方一行 OperationLogUtil.log("模块","操作","描述") 就能记日志,不用注入 bean、不用传参
  • @PostConstruct 抓 Spring bean 静态化,是工具类常见写法
  • 操作人信息从 AuthContext 自动取,调用方完全不用关心"谁在操作"——11 个文件因此零成本接入

评价:API 体验目标合理,耦合点只在实现内部。

判定 说明
保留 一行式日志 API 的体验
🔧 改造 内部把 apes-commons.AuthContext 换成自有 ServiceAuthContext——约 10 行实现改动,11 个调用方一行都不用动

障碍 ④ 账权 Service 间内部调用(UserInfo ↔ Permission ↔ SSO

设计出发点

  • 这是同一业务域内的自然内聚:登录要知道角色、角色挂在套餐上、套餐要校验权限、SSO 要查 sso_config——它们本就该在一起
  • 单体同进程调用,零网络开销(UserInfoServiceImpl 直接 @Autowired PermissionServiceImpl

评价:这不仅不是障碍,反而是该整包带走的部分。它恰恰证明了"账权是一个内聚域"。

判定 说明
全部保留 留在 Identity Service 内部,一个调用都不用动
无必须拆分项 这正是拆服务时"一起搬"的内容

障碍 ⑤ 共享数据库(所有表同一 MySQL)

设计出发点

  • 初期最快:不用设计服务边界、不用碰分布式事务
  • customer_id 共享键多租户,天然一张库(业务表靠这个字段关联 customer_info,不是外键)
  • 表间逻辑关联多,放一起 JOIN 方便;一个 RDS 实例成本最低

评价:早期最务实的选择。这是 6 条里唯一一个"实体层面真必须拆"的。

判定 说明
短期保留 Phase 1-2(模块化隔离、引网关)完全可以不动库,不拆库也能推进
🔧 必须拆分(长期) 要"真正独立"就必须拆——否则账权与业务仍共享存储,故障域/扩缩容/安全策略都分不开。拆库放到 Phase 3,且必须配双写过渡期

障碍 ⑥ AOP 执行顺序依赖(DataSourceHeaderAspect Order=1 + LoginAspect

设计出发点

  • DataSourceHeaderAspectAuthContext.clean() 再切数据源 → 保证每个请求从干净状态开始,防止上一请求的 ThreadLocal 泄漏/串号
  • 然后 LoginAspect(在 apes-commons 里)填充 AuthContext → 保证 Controller 执行业务前上下文已就绪
  • 这个顺序在"单进程内、请求串行经过切面"时完美工作

评价:"请求级清理 + 顺序保证"的防泄漏思路必须保留,它是并发安全的底线。

判定 说明
保留 请求级 ThreadLocal 清理 + 顺序保证的思路(防内存泄漏/串号是刚需)
🔧 改造 职责归属变了——数据源路由可能在网关或各服务内,认证填充改由 auth-sdkAuthHeaderFilter 做,顺序由本地 Filter chain 保证,而非跨 JAR 协商

总分类

障碍 设计出发点是否合理 结论
AuthContext ThreadLocal 合理 保留机制,改造填充源与跨服务传播
apes-commons 黑盒 合理(平台化) 保留思路,收归自有 auth-sdk
OperationLogUtil 静态 合理(便利性) 保留 API,改内部 10 行实现
账权 Service 内部调用 本就该内聚 全部保留,整包带走
共享数据库 ⚠️ 早期务实 短期保留,长期必须拆(Phase 3 + 双写)
AOP 顺序依赖 合理(防泄漏) 保留思路,改造职责归属

一句话总结:6 条里有 4 条半是"好设计绑在了单体上"——思路保留、形态搬迁即可;只有"共享数据库"是实体层面真必须拆的,而"账权 Service 内部调用"根本不是障碍,是拆服务时该一起搬走的内聚域。

真正需要"动刀"的,其实就三件事:

  1. 跨服务上下文传播ThreadLocal → 网关 Header(机制保留)
  2. 存储边界:共享库 → auth_db 独立(Phase 3
  3. 依赖主权:外部 JAR → 自有 auth-sdk(兼容旧包名,业务零改动)

6. 独立服务化可行性论证

6.1 有利因素

因素 说明
Redis 共享会话 登录态存储在 Redis,天然支持分布式,服务拆分后会话无需迁移
无数据库外键约束 业务表与账权表之间是逻辑关联(customer_id),不是物理外键,拆库无 DDL 障碍
业务模块零直接依赖 Trace*/Weight* 不 import 账权 Service,仅通过 AuthContext 间接获取登录态
账权域高内聚 账权 Service 间约 8 处内部调用,全在域内,整包带走即可
AuthContext API 简单 主要调用模式是 AuthContext.getLoginInfo().getCustomer().getId(),可用 SDK 兼容替换

6.2 风险因素

风险 等级 应对
apes-commons 黑盒 收归自有 auth-sdkMaven shade relocation 兼容旧包名
52 个文件引用 AuthContext import 替换即可,方法签名不变
共享数据库拆分 Phase 3 双写过渡期 + 数据一致性校验
AOP 执行顺序 各服务内 Filter chain 保证,不跨 JAR 协商
AccessTokenFilter 耦合 迁移到网关或 Identity Service 入口

6.3 结论

技术上可行。业务模块与账权模块之间不存在直接代码调用(0 个 import),耦合仅通过 AuthContextThreadLocal)间接发生。登录态已存储在 Redis 中天然支持分布式。拆分的基础条件良好。

分阶段实施建议:

阶段 目标 风险 预估
Phase 1 单体内包级隔离 + 接口抽象 5-10 人天
Phase 2 抽取 auth-sdk + 引入网关 10-15 人天
Phase 3 Identity Service 独立部署 + 数据库拆分 15-20 人天
Phase 4 JWT 升级 + 权限注解 + OAuth2 10+ 人天

建议立即启动 Phase 1(风险最低、收益明确)。是否推进 Phase 2-3 取决于是否有多产品线复用账权的需求。


附:分析方法说明

本文档的分析基于以下方法:

  1. 静态代码走查:通过 Agent 子任务深度遍历 src/main/java 全部包结构,读取所有关键 Controller/Service/Entity/Config 源码
  2. Grep 量化统计:使用 ripgrep 对源码树进行精确模式匹配,统计耦合度指标
  3. 依赖追踪:通过 import 语句分析模块间依赖关系
  4. 设计意图推断:从代码写法(AOP 顺序、静态封装、Redis key 设计等)反推设计者的决策出发点
  5. 可行性论证:基于量化数据和架构特征,评估微服务拆分的技术可行性

分析工具链:Agent Explore 子任务 + Grep + Read,分析时间:2026-08-05