Skip to content

refactor(pay): 抽取 apache httpclient 支付实现的公共父类,消除重复代码 - #4082

Open
devin-ai-integration[bot] wants to merge 1 commit into
developfrom
devin/1785470050-refactor-pay-apache-http
Open

refactor(pay): 抽取 apache httpclient 支付实现的公共父类,消除重复代码#4082
devin-ai-integration[bot] wants to merge 1 commit into
developfrom
devin/1785470050-refactor-pay-apache-http

Conversation

@devin-ai-integration

Copy link
Copy Markdown

Summary

用 PMD CPD 扫描全仓库后,weixin-java-payWxPayServiceApacheHttpImplWxPayServiceHttpComponentsImpl 是逻辑层面(非 bean 字段)最大的一处重复:两个类 400+ 行中约 300 行逐字符相同,只有 v2 的 postForBytes / post 在获取 http 客户端的方式上不同(连接池客户端 vs 每次 HttpClientBuilder.build())。任何一侧修复(如之前的 Wechatpay-Serial 公钥模式兼容)都必须手工同步到另一侧。

本次新增包内抽象父类 AbstractWxPayApacheHttpServiceImpl extends BaseWxPayServiceImpl,收敛全部共用逻辑:

AbstractWxPayApacheHttpServiceImpl
  postV3 / patchV3 / postV3WithWechatpaySerial / requestV3 x2 / getV3 /
  getV3WithWechatPaySerial / downloadV3 / putV3 / deleteV3
  configureRequest, createApiV3HttpClient, createHttpClientBuilder,
  createHttpPost x2, createEntry x2, initSSLContext, convertException,
  getWechatPaySerial, logRequestAndResponse, logError

WxPayServiceApacheHttpImpl      -> 仅保留 postForBytes/post x2 + createHttpClient(连接池)
WxPayServiceHttpComponentsImpl  -> 仅保留 postForBytes/post x2 (每次 build 客户端)

行为保持不变,仅有两处细节说明:

  • 三处 RequestConfig.custom()...build() 的重复片段提取为 createRequestConfig(),参数完全一致。
  • 父类不使用 @Slf4j,改为 protected final Logger log = LoggerFactory.getLogger(this.getClass()),因此日志分类仍然是 WxPayServiceApacheHttpImpl / WxPayServiceHttpComponentsImpl(含 WxPayServiceImpl),不影响既有日志配置。

兼容性:两个实现类仍为 public 且仍是 BaseWxPayServiceImpl 的子类,公共方法签名、WxPayServiceImpl extends WxPayServiceApacheHttpImpl 及包内可见的 createHttpClient(boolean) 均未变;新增父类为包内可见,不扩大对外 API。HttpProxyUtils 中指向 createHttpClientBuilder 的注释同步更新。

验证

  • mvn -pl weixin-java-pay -am -DskipTests install 编译通过。
  • 由于根 POM 中 surefire 配置了 <skip>true</skip>,直接用 TestNG 运行了与本次改动相关的用例:WxPayServiceApacheHttpImplConnectionPoolTestConnectionPoolUsageExampleTest,5 个用例全部通过。
  • 依赖真实微信凭据的测试未执行。

Link to Devin session: https://app.devin.ai/sessions/65a1cece5efb4304a7e6b85aaa562d7a
Requested by: @binarywang

WxPayServiceApacheHttpImpl 与 WxPayServiceHttpComponentsImpl 中约 300 行 v3 请求、
请求构造、SSL/代理配置、日志与异常转换逻辑完全重复,现抽取到包内抽象父类
AbstractWxPayApacheHttpServiceImpl,两个实现类仅保留各自的 v2 post 逻辑。

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@binarywang binarywang self-assigned this Jul 31, 2026
@devin-ai-integration

Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 77122707e7

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

* @param requestStr 请求数据
* @return post 请求
*/
protected HttpPost createHttpPost(String url, String requestStr) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 避免将请求构造 helper 变成可覆写 API

当下游已有 WxPayServiceApacheHttpImpl/WxPayServiceHttpComponentsImpl 子类定义同签名的 createHttpPost 时,旧实现里的这些 helper 是 private,不会参与覆盖;现在抽到父类后变成 protectedpost/postV3 中的 this.createHttpPost(...) 会动态分派到用户子类,导致请求体、超时和 v3 请求头构造被意外替换,升级后行为改变。作为公共 SDK 的兼容性重构,建议把这些抽取出的内部 helper 保持包内或不可覆盖,只给两个实现类复用。

AGENTS.md reference: AGENTS.md:L47-L48

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant