| @@ -288,7 +288,17 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||||
| || error.getErrorCode() == ERR_42001 | || error.getErrorCode() == ERR_42001 | ||||
| || error.getErrorCode() == ERR_40014) { | || error.getErrorCode() == ERR_40014) { | ||||
| // 强制设置WxMaConfig的access token过期了,这样在下一次请求里就会刷新access token | // 强制设置WxMaConfig的access token过期了,这样在下一次请求里就会刷新access token | ||||
| this.getWxMaConfig().expireAccessToken(); | |||||
| Lock lock = this.getWxMaConfig().getAccessTokenLock(); | |||||
| lock.lock(); | |||||
| try { | |||||
| if(StringUtils.equals(this.getWxMaConfig().getAccessToken(), accessToken)){ | |||||
| this.getWxMaConfig().expireAccessToken(); | |||||
| } | |||||
| } catch (Exception ex){ | |||||
| this.getWxMaConfig().expireAccessToken(); | |||||
| }finally { | |||||
| lock.unlock(); | |||||
| } | |||||
| if (this.getWxMaConfig().autoRefreshToken()) { | if (this.getWxMaConfig().autoRefreshToken()) { | ||||
| return this.execute(executor, uri, data); | return this.execute(executor, uri, data); | ||||
| } | } | ||||
| @@ -351,7 +351,17 @@ public abstract class BaseWxMpServiceImpl<H, P> implements WxMpService, RequestH | |||||
| */ | */ | ||||
| if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) { | if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) { | ||||
| // 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token | // 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token | ||||
| this.getWxMpConfigStorage().expireAccessToken(); | |||||
| Lock lock = this.getWxMpConfigStorage().getAccessTokenLock(); | |||||
| lock.lock(); | |||||
| try{ | |||||
| if(StringUtils.equals(this.getWxMpConfigStorage().getAccessToken(), accessToken)){ | |||||
| this.getWxMpConfigStorage().expireAccessToken(); | |||||
| } | |||||
| } catch (Exception ex){ | |||||
| this.getWxMpConfigStorage().expireAccessToken(); | |||||
| } finally { | |||||
| lock.unlock(); | |||||
| } | |||||
| if (this.getWxMpConfigStorage().autoRefreshToken()) { | if (this.getWxMpConfigStorage().autoRefreshToken()) { | ||||
| return this.execute(executor, uri, data); | return this.execute(executor, uri, data); | ||||
| } | } | ||||
| @@ -1,9 +1,13 @@ | |||||
| package me.chanjar.weixin.mp.config.impl; | package me.chanjar.weixin.mp.config.impl; | ||||
| import me.chanjar.weixin.common.util.locks.JedisDistributedLock; | |||||
| import me.chanjar.weixin.mp.enums.TicketType; | import me.chanjar.weixin.mp.enums.TicketType; | ||||
| import redis.clients.jedis.Jedis; | import redis.clients.jedis.Jedis; | ||||
| import redis.clients.jedis.JedisPool; | import redis.clients.jedis.JedisPool; | ||||
| import java.util.concurrent.locks.Lock; | |||||
| import java.util.concurrent.locks.ReentrantLock; | |||||
| /** | /** | ||||
| * 基于Redis的微信配置provider. | * 基于Redis的微信配置provider. | ||||
| * | * | ||||
| @@ -17,6 +21,7 @@ import redis.clients.jedis.JedisPool; | |||||
| @SuppressWarnings("hiding") | @SuppressWarnings("hiding") | ||||
| public class WxMpRedisConfigImpl extends WxMpDefaultConfigImpl { | public class WxMpRedisConfigImpl extends WxMpDefaultConfigImpl { | ||||
| private static final String ACCESS_TOKEN_KEY = "wx:access_token:"; | private static final String ACCESS_TOKEN_KEY = "wx:access_token:"; | ||||
| private static final String LOCK_KEY = "wx:lock:"; | |||||
| /** | /** | ||||
| * 使用连接池保证线程安全. | * 使用连接池保证线程安全. | ||||
| @@ -24,6 +29,7 @@ public class WxMpRedisConfigImpl extends WxMpDefaultConfigImpl { | |||||
| private final JedisPool jedisPool; | private final JedisPool jedisPool; | ||||
| private String accessTokenKey; | private String accessTokenKey; | ||||
| private String lockKey; | |||||
| public WxMpRedisConfigImpl(JedisPool jedisPool) { | public WxMpRedisConfigImpl(JedisPool jedisPool) { | ||||
| this.jedisPool = jedisPool; | this.jedisPool = jedisPool; | ||||
| @@ -36,6 +42,11 @@ public class WxMpRedisConfigImpl extends WxMpDefaultConfigImpl { | |||||
| public void setAppId(String appId) { | public void setAppId(String appId) { | ||||
| super.setAppId(appId); | super.setAppId(appId); | ||||
| this.accessTokenKey = ACCESS_TOKEN_KEY.concat(appId); | this.accessTokenKey = ACCESS_TOKEN_KEY.concat(appId); | ||||
| this.lockKey = ACCESS_TOKEN_KEY.concat(appId).concat(":"); | |||||
| accessTokenLock = new JedisDistributedLock(jedisPool, lockKey.concat("accessTokenLock")); | |||||
| jsapiTicketLock = new JedisDistributedLock(jedisPool, lockKey.concat("jsapiTicketLock")); | |||||
| sdkTicketLock = new JedisDistributedLock(jedisPool, lockKey.concat("sdkTicketLock")); | |||||
| cardApiTicketLock = new JedisDistributedLock(jedisPool, lockKey.concat("cardApiTicketLock")); | |||||
| } | } | ||||
| private String getTicketRedisKey(TicketType type) { | private String getTicketRedisKey(TicketType type) { | ||||
| @@ -155,7 +155,18 @@ public class WxOpenComponentServiceImpl implements WxOpenComponentService { | |||||
| */ | */ | ||||
| if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) { | if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) { | ||||
| // 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token | // 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token | ||||
| this.getWxOpenConfigStorage().expireComponentAccessToken(); | |||||
| Lock lock = this.getWxOpenConfigStorage().getComponentAccessTokenLock(); | |||||
| lock.lock(); | |||||
| try { | |||||
| if (StringUtils.equals(componentAccessToken, this.getWxOpenConfigStorage().getComponentAccessToken()){ | |||||
| this.getWxOpenConfigStorage().expireComponentAccessToken(); | |||||
| } | |||||
| } catch (Exception ex) { | |||||
| this.getWxOpenConfigStorage().expireComponentAccessToken(); | |||||
| }finally { | |||||
| lock.unlock(); | |||||
| } | |||||
| if (this.getWxOpenConfigStorage().autoRefreshToken()) { | if (this.getWxOpenConfigStorage().autoRefreshToken()) { | ||||
| return this.post(uri, postData, accessTokenKey); | return this.post(uri, postData, accessTokenKey); | ||||
| } | } | ||||
| @@ -188,7 +199,17 @@ public class WxOpenComponentServiceImpl implements WxOpenComponentService { | |||||
| */ | */ | ||||
| if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) { | if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) { | ||||
| // 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token | // 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token | ||||
| this.getWxOpenConfigStorage().expireComponentAccessToken(); | |||||
| Lock lock = this.getWxOpenConfigStorage().getComponentAccessTokenLock(); | |||||
| lock.lock(); | |||||
| try { | |||||
| if (StringUtils.equals(componentAccessToken, this.getWxOpenConfigStorage().getComponentAccessToken()){ | |||||
| this.getWxOpenConfigStorage().expireComponentAccessToken(); | |||||
| } | |||||
| } catch (Exception ex) { | |||||
| this.getWxOpenConfigStorage().expireComponentAccessToken(); | |||||
| }finally { | |||||
| lock.unlock(); | |||||
| } | |||||
| if (this.getWxOpenConfigStorage().autoRefreshToken()) { | if (this.getWxOpenConfigStorage().autoRefreshToken()) { | ||||
| return this.get(uri, accessTokenKey); | return this.get(uri, accessTokenKey); | ||||
| } | } | ||||