瀏覽代碼

优化微信token缓存逻辑

woody 2 年之前
父節點
當前提交
1e5a38f81c

+ 51 - 18
framework-wechat/src/main/java/com/chelvc/framework/wechat/DefaultWechatHandler.java

@@ -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;

+ 31 - 0
framework-wechat/src/main/java/com/chelvc/framework/wechat/config/WechatProperties.java

@@ -27,6 +27,11 @@ public class WechatProperties {
      */
     private String secret;
 
+    /**
+     * 缓存配置
+     */
+    private Cache cache = new Cache();
+
     /**
      * 公众号配置列表
      */
@@ -98,4 +103,30 @@ public class WechatProperties {
          */
         private String callback;
     }
+
+    /**
+     * Reids缓存配置
+     */
+    @Data
+    public static class Cache {
+        /**
+         * 主机地址
+         */
+        private String host;
+
+        /**
+         * 主机端口
+         */
+        private Integer port;
+
+        /**
+         * 登陆密码
+         */
+        private String password;
+
+        /**
+         * 数据库标识
+         */
+        private Integer database;
+    }
 }