【企业微信】重构会话存档SDK生命周期为ThreadLocal模式#3935
Conversation
OldQi
commented
Mar 18, 2026
- 移除7200秒过期和引用计数机制,解决频繁初始化及线程安全问题
- 每线程持有独立SDK实例,实现懒初始化和线程内复用
- 新增closeThreadLocalSdk()和closeAllSdks()接口,用于显式释放资源
- 废弃WxCpConfigStorage中旧的SDK管理方法及相关字段,保留兼容实现
- 更新WxCpMsgAuditServiceImpl,实现ThreadLocal管理SDK实例
- 修改API调用逻辑,移除获取和释放SDK的旧流程,简化调用流程
- 补充单元测试覆盖多线程及线程池场景验证安全性
- 更新相关文档,增加使用示例与注意事项指导正确使用方法
- 移除7200秒过期和引用计数机制,解决频繁初始化及线程安全问题 - 每线程持有独立SDK实例,实现懒初始化和线程内复用 - 新增closeThreadLocalSdk()和closeAllSdks()接口,用于显式释放资源 - 废弃WxCpConfigStorage中旧的SDK管理方法及相关字段,保留兼容实现 - 更新WxCpMsgAuditServiceImpl,实现ThreadLocal管理SDK实例 - 修改API调用逻辑,移除获取和释放SDK的旧流程,简化调用流程 - 补充单元测试覆盖多线程及线程池场景验证安全性 - 更新相关文档,增加使用示例与注意事项指导正确使用方法
- 将获取或初始化SDK的方法替换为直接创建SDK - 简化了SDK的调用流程 - 提高代码清晰度和维护性
- 移除 managedSdks 集合及相关代码,不再统一追踪所有SDK实例 - 采用ThreadLocal懒初始化,线程内部复用SDK实例 - closeAllSdks() 方法改为调用 closeThreadLocalSdk(),只清理当前线程资源 - 保留旧API方法,内部调用统一替换为 getOrInitThreadLocalSdk() - 文档更新,明确多线程和多实例场景下的SDK管理及DestroySdk调用规范 - 删除手动调用 Finance.DestroySdk() 的旧测试代码示例,防止误用造成内存泄漏
This reverts commit add61c1.
|
auggie review |
🤖 Augment PR SummarySummary: This PR refactors the WeCom (企业微信) message-audit SDK lifecycle from a shared/expiry/ref-count model to a per-thread Changes:
Technical Notes: Uses a concurrent set to track created SDK ids for bulk cleanup; callers in thread pools are expected to call 🤖 Was this summary useful? React with 👍 or 👎 |
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMsgAuditServiceImpl.java
Show resolved
Hide resolved
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMsgAuditServiceImpl.java
Outdated
Show resolved
Hide resolved
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMsgAuditServiceImpl.java
Show resolved
Hide resolved
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMsgAuditServiceImpl.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Pull request overview
本次 PR 针对企业微信“会话存档”能力重构原生 Finance SDK 的生命周期管理方式,目标是减少频繁初始化/销毁并降低多线程共享句柄带来的线程安全风险,通过 ThreadLocal 让每个线程持有独立 SDK 实例,并提供显式资源释放接口。
Changes:
- 在
WxCpMsgAuditServiceImpl中引入ThreadLocal<Long>与managedSdks,新增closeThreadLocalSdk()/closeAllSdks(),并将推荐 API(不暴露 sdk)切换为线程内复用模式。 - 将
WxCpConfigStorage与WxCpDefaultConfigImpl中旧的“SDK缓存/过期/引用计数”相关字段与方法标记为@Deprecated以保持兼容。 - 调整测试用例示例,强调线程池场景需在 finally 中调用
closeThreadLocalSdk();新增一份设计说明文档。
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMsgAuditServiceImpl.java | 用 ThreadLocal 管理会话存档 SDK,新增显式关闭接口并简化推荐 API 调用链 |
| weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMsgAuditService.java | 对外暴露 closeThreadLocalSdk()/closeAllSdks() 生命周期接口 |
| weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpConfigStorage.java | 废弃旧的 SDK 缓存/过期/引用计数 API(保留以兼容) |
| weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpDefaultConfigImpl.java | 废弃旧字段与实现方法,继续提供兼容行为 |
| weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMsgAuditTest.java | 更新示例测试:在 finally 调用 closeThreadLocalSdk() |
| docs/giggly-pondering-turtle.md | 新增 ThreadLocal 生命周期重构方案说明文档 |
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMsgAuditServiceImpl.java
Outdated
Show resolved
Hide resolved
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpConfigStorage.java
Outdated
Show resolved
Hide resolved
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMsgAuditServiceImpl.java
Outdated
Show resolved
Hide resolved
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMsgAuditServiceImpl.java
Outdated
Show resolved
Hide resolved
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMsgAuditServiceImpl.java
Outdated
Show resolved
Hide resolved
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMsgAuditServiceImpl.java
Outdated
Show resolved
Hide resolved
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMsgAuditTest.java
Show resolved
Hide resolved
|
@OldQi 麻烦处理下上面的review建议,如果无需修改,备注后resolve conversation即可 |
- 移除7200秒过期机制和引用计数,采用ThreadLocal为每个线程持有独立SDK实例 - 新增getOrInitThreadLocalSdk()方法实现线程内SDK复用,避免频繁初始化/销毁 - 添加closeThreadLocalSdk()和closeAllSdks()方法用于显式清理SDK资源 - 更新getChatRecords等API方法使用ThreadLocal模式替代原有的acquire/release机制 - 修复多线程并发时的double-free问题,改进资源管理的安全性 - 优化文件分片下载的流处理,使用try-with-resources避免资源泄漏 - 标记旧的SDK管理方法为@deprecated,提供向后兼容性保证
- 移除了关于暴露 SDK 的废弃方法注释 - 删除了推荐使用 getChatRecords 的废弃提示 - 简化了方法文档,保留核心功能说明
- 添加废弃说明提醒用户使用新版本文档 - 指引用户迁移到CP_MSG_AUDIT_THREADLOCAL_LIFECYCLE_REFACTOR.md
- 修正了关于Finance.DestroySdk()自动执行的错误描述 - 明确了无论线程池还是独立线程都需要显式调用closeThreadLocalSdk() - 强调了native资源泄漏的风险和预防措施 - 更新了测试代码中的注释说明 - 完善了注意事项中的线程安全相关描述
- 在获取失效SDK句柄时抛出WxErrorException异常 - 添加详细的错误信息提示调用closeAllSdks方法 - 确保线程安全的SDK句柄管理机制
- 修改线程安全警告信息,从重新初始化改为检查调用逻辑 - 移除失效SDK句柄后抛出异常提示检查closeAllSdks调用
- 简化了无效SDK句柄的处理流程 - 统一了异常抛出逻辑的代码结构 - 移除了不必要的else分支提高代码可读性 - 保持了原有的警告日志记录功能 - 维持了线程本地变量的清理操作
|
已处理review建议 |
|
很多都还没有resolve 吧? |
|
ok,resolve 了,以为改了代码的你这边点resolve |