|
@@ -10,7 +10,6 @@ import java.util.function.Supplier;
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
import javax.servlet.http.HttpSession;
|
|
|
|
|
|
-import com.chelvc.framework.base.context.ApplicationContextHolder;
|
|
|
import com.chelvc.framework.base.context.SessionContextHolder;
|
|
|
import com.chelvc.framework.base.model.Terminal;
|
|
|
import com.chelvc.framework.base.util.DecimalUtils;
|
|
@@ -27,6 +26,7 @@ import lombok.NonNull;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
|
|
|
import org.springframework.data.redis.core.RedisTemplate;
|
|
|
import org.springframework.http.HttpEntity;
|
|
|
import org.springframework.http.HttpHeaders;
|
|
@@ -95,6 +95,39 @@ public class DefaultWechatHandler implements WechatHandler {
|
|
|
private final RedisTemplate<String, Object> redisTemplate;
|
|
|
private final WechatProperties properties;
|
|
|
private final Map<String, String> tokens = Maps.newHashMap();
|
|
|
+ private RedisTemplate<String, Object> cache;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取缓存RedisTemplate实例
|
|
|
+ *
|
|
|
+ * @return RedisTemplate实例
|
|
|
+ */
|
|
|
+ private RedisTemplate<String, Object> getCache() {
|
|
|
+ // 获取缓存配置
|
|
|
+ WechatProperties.Cache config = this.properties.getCache();
|
|
|
+ String host = ObjectUtils.ifNull(config, WechatProperties.Cache::getHost);
|
|
|
+ Integer port = ObjectUtils.ifNull(config, WechatProperties.Cache::getPort);
|
|
|
+ if (StringUtils.isEmpty(host) || Objects.isNull(port)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 初始化RedisTemplate实例
|
|
|
+ if (this.cache == null) {
|
|
|
+ synchronized (this) {
|
|
|
+ if (this.cache == null) {
|
|
|
+ String password = ObjectUtils.ifNull(config, WechatProperties.Cache::getPassword);
|
|
|
+ Integer database = ObjectUtils.ifNull(config, WechatProperties.Cache::getDatabase, () -> 0);
|
|
|
+ RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
|
|
|
+ configuration.setPort(port);
|
|
|
+ configuration.setHostName(host);
|
|
|
+ configuration.setPassword(password);
|
|
|
+ configuration.setDatabase(database);
|
|
|
+ this.cache = RedisUtils.template(configuration);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return this.cache;
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 根据支付交易类型获取Appid
|
|
@@ -224,25 +257,25 @@ public class DefaultWechatHandler implements WechatHandler {
|
|
|
@Override
|
|
|
public String refreshAccessToken(@NonNull String appid, @NonNull String secret) {
|
|
|
String key = ACCESS_TOKEN_PREFIX + appid;
|
|
|
+ RedisTemplate<String, Object> cache = this.getCache();
|
|
|
synchronized (key.intern()) {
|
|
|
- String token = ApplicationContextHolder.getProperty("platform.wechat.access.token." + appid);
|
|
|
- if (StringUtils.isEmpty(token)) {
|
|
|
- token = (String) this.redisTemplate.opsForValue().get(key);
|
|
|
- if (StringUtils.isEmpty(token) || Objects.equals(token, this.tokens.get(key))) {
|
|
|
- String url = String.format(ACCESS_TOKEN_URL, appid, secret);
|
|
|
- if (log.isDebugEnabled()) {
|
|
|
- log.debug("Wechat request: {}", url);
|
|
|
- }
|
|
|
- token = RedisUtils.lockAround(key + ":lock", () -> {
|
|
|
- WechatAccessToken accessToken =
|
|
|
- WechatUtils.execute(() -> this.restTemplate.getForObject(url, WechatAccessToken.class));
|
|
|
- long duration = accessToken.getDuration() - 60;
|
|
|
- this.redisTemplate.opsForValue().set(key, accessToken.getToken(), duration, TimeUnit.SECONDS);
|
|
|
- return accessToken.getToken();
|
|
|
- }, () -> {
|
|
|
- throw new IllegalStateException("Get wechat access token timeout");
|
|
|
- });
|
|
|
+ String token = cache == null ? null : (String) cache.opsForValue().get(key);
|
|
|
+ if (StringUtils.isEmpty(token)
|
|
|
+ && (StringUtils.isEmpty(token = (String) this.redisTemplate.opsForValue().get(key))
|
|
|
+ || Objects.equals(token, this.tokens.get(key)))) {
|
|
|
+ String url = String.format(ACCESS_TOKEN_URL, appid, secret);
|
|
|
+ if (log.isDebugEnabled()) {
|
|
|
+ log.debug("Wechat request: {}", url);
|
|
|
}
|
|
|
+ token = RedisUtils.lockAround(key + ":lock", () -> {
|
|
|
+ WechatAccessToken accessToken =
|
|
|
+ WechatUtils.execute(() -> this.restTemplate.getForObject(url, WechatAccessToken.class));
|
|
|
+ long duration = accessToken.getDuration() - 60;
|
|
|
+ this.redisTemplate.opsForValue().set(key, accessToken.getToken(), duration, TimeUnit.SECONDS);
|
|
|
+ return accessToken.getToken();
|
|
|
+ }, () -> {
|
|
|
+ throw new IllegalStateException("Get wechat access token timeout");
|
|
|
+ });
|
|
|
}
|
|
|
this.tokens.put(key, token);
|
|
|
return token;
|