diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/WxPayConfigHolder.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/WxPayConfigHolder.java new file mode 100644 index 0000000000..98d064475e --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/WxPayConfigHolder.java @@ -0,0 +1,35 @@ +package com.github.binarywang.wxpay.config; + +/** + * 微信支付配置策略. + * + * @author zenghao + * @date 2021/3/12 + */ +public class WxPayConfigHolder { + + private static final ThreadLocal THREAD_LOCAL = ThreadLocal.withInitial(() -> "default"); + + /** + * 获取当前微信支付配置策略. + * @return 当前微信支付配置策略 + */ + public static String get() { + return THREAD_LOCAL.get(); + } + + /** + * 设置当前微信支付配置策略. + * @param label 策略名称 + */ + public static void set(final String label) { + THREAD_LOCAL.set(label); + } + + /** + * 此方法需要用户根据自己程序代码,在适当位置手动触发调用,本SDK里无法判断调用时机. + */ + public static void remove() { + THREAD_LOCAL.remove(); + } +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java index 0caba53c2f..586db1cc2a 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java @@ -35,6 +35,53 @@ public interface WxPayService { */ String getPayBaseUrl(); + /** + * Map里 加入新的 {@link WxPayConfig},适用于动态添加新的微信公众号配置. + * + * @param mchId 商户号id + * @param wxPayConfig 新的微信配置 + */ + void addConfig(String mchId, WxPayConfig wxPayConfig); + + /** + * 从 Map中 移除 {@link String mchId} 所对应的 {@link WxPayConfig},适用于动态移除微信公众号配置. + * + * @param mchId 对应公众号的标识 + */ + void removeConfig(String mchId); + + /** + * 注入多个 {@link WxPayConfig} 的实现. 并为每个 {@link WxPayConfig} 赋予不同的 {@link String mchId} 值 + * 随机采用一个{@link String mchId}进行Http初始化操作 + * + * @param wxPayConfigs WxPayConfig map + */ + void setMultiConfig(Map wxPayConfigs); + + /** + * 注入多个 {@link WxPayConfig} 的实现. 并为每个 {@link WxPayConfig} 赋予不同的 {@link String label} 值 + * + * @param wxPayConfigs WxPayConfig map + * @param defaultMchId 设置一个{@link WxPayConfig} 所对应的{@link String mchId}进行Http初始化 + */ + void setMultiConfig(Map wxPayConfigs, String defaultMchId); + + /** + * 进行相应的公众号切换. + * + * @param mchId 公众号标识 + * @return 切换是否成功 boolean + */ + boolean switchover(String mchId); + + /** + * 进行相应的公众号切换. + * + * @param mchId 公众号标识 + * @return 切换成功 ,则返回当前对象,方便链式调用,否则抛出异常 + */ + WxPayService switchoverTo(String mchId); + /** * 发送post请求,得到响应字节数组. * diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java index 35dcf1d890..cf1a62c697 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java @@ -13,6 +13,7 @@ import com.github.binarywang.wxpay.bean.request.*; import com.github.binarywang.wxpay.bean.result.*; import com.github.binarywang.wxpay.config.WxPayConfig; +import com.github.binarywang.wxpay.config.WxPayConfigHolder; import com.github.binarywang.wxpay.constant.WxPayConstants; import com.github.binarywang.wxpay.constant.WxPayConstants.SignType; import com.github.binarywang.wxpay.constant.WxPayConstants.TradeType; @@ -21,6 +22,7 @@ import com.github.binarywang.wxpay.util.SignUtils; import com.github.binarywang.wxpay.util.XmlConfig; import com.google.common.base.Joiner; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; import jodd.io.ZipUtil; import me.chanjar.weixin.common.error.WxRuntimeException; @@ -65,7 +67,7 @@ public abstract class BaseWxPayServiceImpl implements WxPayService { private final MarketingMediaService marketingMediaService = new MarketingMediaServiceImpl(this); private final MarketingFavorService marketingFavorService = new MarketingFavorServiceImpl(this); - protected WxPayConfig config; + protected Map configMap; @Override public EntPayService getEntPayService() { @@ -119,12 +121,78 @@ public void setEntPayService(EntPayService entPayService) { @Override public WxPayConfig getConfig() { - return this.config; + if (this.configMap.size() == 1) { + // 只有一个商户号,直接返回其配置即可 + return this.configMap.values().iterator().next(); + } + return this.configMap.get(WxPayConfigHolder.get()); } @Override public void setConfig(WxPayConfig config) { - this.config = config; + final String defaultMchId = config.getMchId(); + this.setMultiConfig(ImmutableMap.of(defaultMchId, config), defaultMchId); + } + + @Override + public void addConfig(String mchId, WxPayConfig wxPayConfig) { + synchronized (this) { + if (this.configMap == null) { + this.setConfig(wxPayConfig); + } else { + WxPayConfigHolder.set(mchId); + this.configMap.put(mchId, wxPayConfig); + } + } + } + + @Override + public void removeConfig(String mchId) { + synchronized (this) { + if (this.configMap.size() == 1) { + this.configMap.remove(mchId); + log.warn("已删除最后一个商户号配置:{},须立即使用setConfig或setMultiConfig添加配置", mchId); + return; + } + if (WxPayConfigHolder.get().equals(mchId)) { + this.configMap.remove(mchId); + final String defaultMpId = this.configMap.keySet().iterator().next(); + WxPayConfigHolder.set(defaultMpId); + log.warn("已删除默认商户号配置,商户号【{}】被设为默认配置", defaultMpId); + return; + } + this.configMap.remove(mchId); + } + } + + @Override + public void setMultiConfig(Map wxPayConfigs) { + this.setMultiConfig(wxPayConfigs, wxPayConfigs.keySet().iterator().next()); + } + + @Override + public void setMultiConfig(Map wxPayConfigs, String defaultMchId) { + this.configMap = Maps.newHashMap(wxPayConfigs); + WxPayConfigHolder.set(defaultMchId); + } + + @Override + public boolean switchover(String mchId) { + if (this.configMap.containsKey(mchId)) { + WxPayConfigHolder.set(mchId); + return true; + } + log.error("无法找到对应【{}】的商户号配置信息,请核实!", mchId); + return false; + } + + @Override + public WxPayService switchoverTo(String mchId) { + if (this.configMap.containsKey(mchId)) { + WxPayConfigHolder.set(mchId); + return this; + } + throw new WxRuntimeException(String.format("无法找到对应【%s】的商户号配置信息,请核实!", mchId)); } @Override