🎨 #1294 优化getAccessToken方法,解决并发时重复刷新的问题

This commit is contained in:
kennywgx 2019-11-22 14:58:40 +08:00 committed by Binary Wang
parent 2faac86310
commit dc89396ead
4 changed files with 46 additions and 0 deletions

View File

@ -74,6 +74,9 @@ public class WxMpServiceHttpClientImpl extends BaseWxMpServiceImpl<CloseableHttp
Lock lock = config.getAccessTokenLock();
lock.lock();
try {
if (!config.isAccessTokenExpired() && !forceRefresh) {
return config.getAccessToken();
}
String url = String.format(GET_ACCESS_TOKEN_URL.getUrl(config), config.getAppId(), config.getSecret());
try {
HttpGet httpGet = new HttpGet(url);

View File

@ -59,6 +59,9 @@ public class WxMpServiceJoddHttpImpl extends BaseWxMpServiceImpl<HttpConnectionP
Lock lock = config.getAccessTokenLock();
lock.lock();
try {
if (!config.isAccessTokenExpired() && !forceRefresh) {
return config.getAccessToken();
}
String url = String.format(GET_ACCESS_TOKEN_URL.getUrl(config), config.getAppId(), config.getSecret());
HttpRequest request = HttpRequest.get(url);

View File

@ -48,6 +48,9 @@ public class WxMpServiceOkHttpImpl extends BaseWxMpServiceImpl<OkHttpClient, OkH
Lock lock = config.getAccessTokenLock();
lock.lock();
try {
if (!config.isAccessTokenExpired() && !forceRefresh) {
return config.getAccessToken();
}
String url = String.format(GET_ACCESS_TOKEN_URL.getUrl(config), config.getAppId(), config.getSecret());
Request request = new Request.Builder().url(url).get().build();

View File

@ -1,6 +1,11 @@
package me.chanjar.weixin.mp.api.impl;
import com.google.common.collect.Sets;
import com.google.inject.Inject;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.WxNetCheckResult;
import me.chanjar.weixin.common.error.WxErrorException;
@ -14,6 +19,7 @@ import org.testng.annotations.Test;
import java.util.Arrays;
import static org.assertj.core.api.Assertions.assertThat;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
@ -114,4 +120,35 @@ public class BaseWxMpServiceImplTest {
public void testShortUrl_with_exceptional_url() throws WxErrorException {
this.wxService.shortUrl("http://www.baidu.com/test?redirect_count=1&access_token=123");
}
@Test
public void refreshAccessTokenDuplicatelyTest() throws InterruptedException {
// 测试多线程刷新accessToken时是否重复刷新
wxService.getWxMpConfigStorage().expireAccessToken();
final Set<String> set = Sets.newConcurrentHashSet();
Runnable r = new Runnable() {
@Override
public void run() {
try {
String accessToken = wxService.getAccessToken();
set.add(accessToken);
} catch (WxErrorException e) {
e.printStackTrace();
}
}
};
final int threadNumber = 10;
ExecutorService executorService = Executors.newFixedThreadPool(threadNumber);
for ( int i = 0; i < threadNumber; i++ ) {
executorService.submit(r);
}
executorService.shutdown();
boolean isTerminated = executorService.awaitTermination(15, TimeUnit.SECONDS);
System.out.println("isTerminated: " + isTerminated);
System.out.println("times of refreshing accessToken: " + set.size());
assertEquals(set.size(), 1);
}
}