GoForum🌐 V2EX

支付中台系统,基于 jeepay 重构了 2 天,目标是做企业部署发行版遇到的问题分享

5wunian · 2026-05-22 21:53 · 0 次点赞 · 6 条回复

Spring Boot 3.x 循环依赖实战:从 allow-circular-references 到纯 DAG ,一个支付系统的重构之旅

项目背景:Jeepay 计全支付,Spring Boot 3.3.7 + MyBatis-Plus + Vue 3 ,多模块 Maven 项目。

  1. 前端集成引发的连锁反应

原本前后端分离部署( Nginx + 独立前端容器),想把前端 dist 直接打进 JAR 简化部署。几个坑:

  • Vue SPA 路由 fallback:Spring Boot 3.x 默认用 PathPatternParser ,addViewControllers 不支持 {spring:\w+} 正则。最终用 @Order(HIGHEST_PRECEDENCE) 的 Filter 拦截无后缀路径 forward 到 index.html 。
  • Spring Security 6 ignoring() 不生效:日志明确警告 You are asking Spring Security to ignore… This is not recommended 。改为 authorizeHttpRequests().permitAll() 才生效。
  • 字体文件 401:Security 的静态资源豁免模式漏了 .woff/.woff2/.ttf/.eot 。
  • 前端构建 API baseURL 双层 /api/api/:VITE_API_BASE_URL=/api 拼接 url: ‘/api/xxx’ → /api/api/xxx 。改为空值。
  1. 发行包瘦身:260MB → 120MB

三个模块的 fat JAR 共 288MB ,其中 130 个公共依赖(72MB) 重复存储 3 次。方案:

  • 去掉未用依赖:jaxb-api(零 import)、mysql-connector-j(纯配置模块不需要)、activemq(仅编译,运行时用 RabbitMQ)
  • 共享 lib:maven-dependency-plugin 收集所有传递依赖到 lib/(自动去重 182 个),antrun 解压 fat JAR 提取 BOOT-INF/classes/ 打包为 flat thin JAR(1.7-5MB)
  • 启动方式:从 java -jar fat.jar 改为 java -cp “lib/*:apps/app.jar” MainClass
  1. 循环依赖根治

去掉 allow-circular-references: true 后直接启动,Spring Boot 3.x 严格检测报出完整依赖链:

┌─────┐ │ SysConfigService 自引用 (删 @Autowired self ,直接用 this) ↑ ↓ │ IsvInfoService 自引用 (同上)

修复策略:

  • 自引用:删字段,改用 this.xxx()
  • 三角循环( PayInterfaceConfigService ↔ MchAppService/MchInfoService ):PayInterfaceConfigService.selectAllPayIfConfigListByAppId() 内部反向调用了 mchAppService.getById() 和 mchInfoService.getById()——这些只是 MyBatis-Plus 的简单 CRUD 委托。将这两个查询上移到 Controller 层,Service 方法改为接收 MchInfo 参数,依赖方向恢复。
  • 两两循环:MchInfoService 注入 IsvInfoService 只是为了 getById(),IsvInfoService 注入 MchInfoService 只是为了 count()。直接替换为对应的 Mapper 注入,因为 MyBatis-Plus 的 ServiceImpl.getById() 底层就是 BaseMapper.selectById()。

关键认知:

  1. 依赖只能单向流动。找到”谁在反向调用”就是断环点。

  2. 大多数循环依赖是 CRUD 委托导致的。ServiceImpl 包装 BaseMapper ,循环往往是因为 A 需要 B 的 getById(),B 需要 A 的 count()——直接用 Mapper 替代 Service 注入,不改任何业务逻辑。

  3. 不要用 @Lazy 、不要用 allow-circular-references ,这些都是掩耳盗铃。Spring Boot 3.x 默认禁止循环是为了逼你写出正确的分层。

  4. 最终效果

┌───────────────────────────┬────────┬───────────────┐ │ 指标 │ 修复前 │ 修复后 │ ├───────────────────────────┼────────┼───────────────┤ │ 发行包大小 │ 260 MB │ 120 MB (-54%) │ ├───────────────────────────┼────────┼───────────────┤ │ 循环依赖 │ 5 个 │ 0 │ ├───────────────────────────┼────────┼───────────────┤ │ allow-circular-references │ true │ 已移除 │ ├───────────────────────────┼────────┼───────────────┤ │ @Lazy │ 2 处 │ 0 │ ├───────────────────────────┼────────┼───────────────┤ │ 启动时间 │ ~8s │ ~4s │ └───────────────────────────┴────────┴───────────────┘

6 条回复
5wunian · 2026-05-22 21:53
#1

还增加了 openlist 的 s3 存储支持。

5wunian · 2026-05-22 21:53
#2

有自建需求的留言邮箱。

5wunian · 2026-05-22 21:58
#3

从开源建立的 jeepay ,到商业片的发行包,中间有一大堆需要配置配置的东西。为此做了大量的自动化部署工具脚本。

5wunian · 2026-05-22 22:13
#4

目前已经完成了一个应用接入支付。有需要接入支付的,可以联系,提供技术支持。

5wunian · 2026-05-22 22:13
#5

已经完成了支付备案,网站备案,可以完成全链路的动作。

Mandyer · 2026-05-22 22:33
#6

YW9odW4yMDE4QGdtYWlsLmNvbQ== 楼主来一份,谢谢

添加回复
你还需要 登录 后发表回复

登录后可发帖和回复

登录 注册
主题信息
作者: 5wunian
发布: 2026-05-22
点赞: 0
回复: 0