Skip to content

Commit 2c108c4

Browse files
authored
🎨 #2138 【企业微信】优化Redisson实现类,可单独配置provider的redis key,并使keyPrefix可设置
1 parent 317c98b commit 2c108c4

File tree

2 files changed

+55
-14
lines changed

2 files changed

+55
-14
lines changed

Diff for: weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpTpRedissonConfigImpl.java

+34-9
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ public class WxCpTpRedissonConfigImpl implements WxCpTpConfigStorage, Serializab
2626
private final WxRedisOps wxRedisOps;
2727

2828
//redis里面key的统一前缀
29-
private final String keyPrefix = "";
29+
//private final String keyPrefix = "";//4.0.9.B 有final为不可设置,去掉final改为可设置
30+
private String keyPrefix = "";
3031

3132
private final String suiteAccessTokenKey = ":suiteAccessTokenKey:";
3233

@@ -298,23 +299,23 @@ public void updateAuthSuiteJsApiTicket(String authCorpId, String jsApiTicket, in
298299
@Override
299300
public boolean isProviderTokenExpired() {
300301
//remain time to live in seconds, or key not exist
301-
return wxRedisOps.getExpire(keyWithPrefix(providerTokenKey)) == 0L || wxRedisOps.getExpire(keyWithPrefix(providerTokenKey)) == -2;
302+
return wxRedisOps.getExpire(providerKeyWithPrefix(providerTokenKey)) == 0L || wxRedisOps.getExpire(providerKeyWithPrefix(providerTokenKey)) == -2;
302303
}
303304

304305
@Override
305306
public void updateProviderToken(String providerToken, int expiredInSeconds) {
306-
wxRedisOps.setValue(keyWithPrefix(providerTokenKey), providerToken, expiredInSeconds, TimeUnit.SECONDS);
307+
wxRedisOps.setValue(providerKeyWithPrefix(providerTokenKey), providerToken, expiredInSeconds, TimeUnit.SECONDS);
307308
}
308309

309310
@Override
310311
public String getProviderToken() {
311-
return wxRedisOps.getValue(keyWithPrefix(providerTokenKey));
312+
return wxRedisOps.getValue(providerKeyWithPrefix(providerTokenKey));
312313
}
313314

314315
@Override
315316
public WxCpProviderToken getProviderTokenEntity() {
316-
String providerToken = wxRedisOps.getValue(keyWithPrefix(providerTokenKey));
317-
Long expire = wxRedisOps.getExpire(keyWithPrefix(providerTokenKey));
317+
String providerToken = wxRedisOps.getValue(providerKeyWithPrefix(providerTokenKey));
318+
Long expire = wxRedisOps.getExpire(providerKeyWithPrefix(providerTokenKey));
318319

319320
if (StringUtils.isBlank(providerToken) || expire == null || expire == 0 || expire == -2) {
320321
return new WxCpProviderToken();
@@ -328,7 +329,7 @@ public WxCpProviderToken getProviderTokenEntity() {
328329

329330
@Override
330331
public void expireProviderToken() {
331-
wxRedisOps.expire(keyWithPrefix(providerTokenKey), 0, TimeUnit.SECONDS);
332+
wxRedisOps.expire(providerKeyWithPrefix(providerTokenKey), 0, TimeUnit.SECONDS);
332333
}
333334

334335
/**
@@ -361,7 +362,7 @@ public File getTmpDirFile() {
361362

362363
@Override
363364
public Lock getProviderAccessTokenLock() {
364-
return getLockByKey(String.join(":", this.corpId, LOCKER_PROVIDER_ACCESS_TOKEN));
365+
return getProviderLockByKey(String.join(":", this.corpId, LOCKER_PROVIDER_ACCESS_TOKEN));
365366
}
366367

367368
@Override
@@ -390,6 +391,15 @@ private Lock getLockByKey(String key) {
390391
return this.wxRedisOps.getLock(String.join(":", keyWithPrefix(LOCK_KEY + this.suiteId), key));
391392
}
392393

394+
/**
395+
* 单独处理provider,且不应和suite 有关系
396+
* @param key
397+
* @return
398+
*/
399+
private Lock getProviderLockByKey(String key) {
400+
return this.wxRedisOps.getLock(String.join(":", providerKeyWithPrefix(LOCK_KEY), key));
401+
}
402+
393403
@Override
394404
public ApacheHttpClientBuilder getApacheHttpClientBuilder() {
395405
return this.apacheHttpClientBuilder;
@@ -406,7 +416,22 @@ public String toString() {
406416
return WxCpGsonBuilder.create().toJson(this);
407417
}
408418

419+
/**
420+
* 一个provider 会有多个suite,需要唯一标识作为前缀
421+
* @param key
422+
* @return
423+
*/
409424
private String keyWithPrefix(String key) {
410-
return keyPrefix + key;
425+
return keyPrefix +":"+suiteId+":" + key;
426+
}
427+
428+
/**
429+
* provider 应该独享一个key,且不和任何suite关联
430+
* 一个provider 会有多个suite,不同的suite 都应该指向同一个provider 的数据
431+
* @param key
432+
* @return
433+
*/
434+
private String providerKeyWithPrefix(String key) {
435+
return keyPrefix +":"+corpId+":" + key;
411436
}
412437
}

Diff for: weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/BaseWxCpTpServiceImpl.java

+21-5
Original file line numberDiff line numberDiff line change
@@ -305,18 +305,25 @@ public String get(String url, String queryParam) throws WxErrorException {
305305

306306
@Override
307307
public String post(String url, String postData) throws WxErrorException {
308-
return execute(SimplePostRequestExecutor.create(this), url, postData);
308+
return execute(SimplePostRequestExecutor.create(this), url, postData,false);
309+
}
310+
311+
public String post(String url, String postData,boolean withoutSuiteAccessToken) throws WxErrorException {
312+
return execute(SimplePostRequestExecutor.create(this), url, postData,withoutSuiteAccessToken);
309313
}
310314

311315
/**
312316
* 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求.
313317
*/
314318
@Override
315319
public <T, E> T execute(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException {
320+
return execute(executor, uri, data,false);
321+
}
322+
public <T, E> T execute(RequestExecutor<T, E> executor, String uri, E data,boolean withoutSuiteAccessToken) throws WxErrorException {
316323
int retryTimes = 0;
317324
do {
318325
try {
319-
return this.executeInternal(executor, uri, data);
326+
return this.executeInternal(executor, uri, data,withoutSuiteAccessToken);
320327
} catch (WxErrorException e) {
321328
if (retryTimes + 1 > this.maxRetryTimes) {
322329
log.warn("重试达到最大次数【{}】", this.maxRetryTimes);
@@ -347,14 +354,22 @@ public <T, E> T execute(RequestExecutor<T, E> executor, String uri, E data) thro
347354
}
348355

349356
protected <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException {
357+
return executeInternal( executor, uri,data,false);
358+
}
359+
protected <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data,boolean withoutSuiteAccessToken) throws WxErrorException {
350360
E dataForLog = DataUtils.handleDataWithSecret(data);
351361

352362
if (uri.contains("suite_access_token=")) {
353363
throw new IllegalArgumentException("uri参数中不允许有suite_access_token: " + uri);
354364
}
355-
String suiteAccessToken = getSuiteAccessToken(false);
365+
String uriWithAccessToken;
366+
if(!withoutSuiteAccessToken){
367+
String suiteAccessToken = getSuiteAccessToken(false);
368+
uriWithAccessToken = uri + (uri.contains("?") ? "&" : "?") + "suite_access_token=" + suiteAccessToken;
369+
}else{
370+
uriWithAccessToken = uri;
371+
}
356372

357-
String uriWithAccessToken = uri + (uri.contains("?") ? "&" : "?") + "suite_access_token=" + suiteAccessToken;
358373

359374
try {
360375
T result = executor.execute(uriWithAccessToken, data, WxType.CP);
@@ -452,9 +467,10 @@ public String getWxCpProviderToken() throws WxErrorException {
452467
JsonObject jsonObject = new JsonObject();
453468
jsonObject.addProperty("corpid", configStorage.getCorpId());
454469
jsonObject.addProperty("provider_secret", configStorage.getProviderSecret());
470+
//providerAccessToken 的获取不需要suiteAccessToken ,一不必要,二可以提高效率
455471
WxCpProviderToken wxCpProviderToken =
456472
WxCpProviderToken.fromJson(this.post(this.configStorage.getApiUrl(GET_PROVIDER_TOKEN)
457-
, jsonObject.toString()));
473+
, jsonObject.toString(),true));
458474
String providerAccessToken = wxCpProviderToken.getProviderAccessToken();
459475
Integer expiresIn = wxCpProviderToken.getExpiresIn();
460476

0 commit comments

Comments
 (0)