ソースを参照

:art: 修复微信开发平台部分问题,并对企业微信新增多种 redis 存储实现支持

Forever杨 2 年 前
コミット
e50457892d
19 ファイル変更527 行追加212 行削除
  1. 1 1
      spring-boot-starters/wx-java-cp-spring-boot-starter/README.md
  2. 12 0
      spring-boot-starters/wx-java-cp-spring-boot-starter/pom.xml
  3. 7 1
      spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/config/WxCpStorageAutoConfiguration.java
  4. 25 1
      spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/properties/WxCpProperties.java
  5. 46 0
      spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/properties/WxCpRedisProperties.java
  6. 2 4
      spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/storage/AbstractWxCpConfigStorageConfiguration.java
  7. 74 0
      spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/storage/WxCpInJedisConfigStorageConfiguration.java
  8. 41 0
      spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/storage/WxCpInRedisTemplateConfigStorageConfiguration.java
  9. 65 0
      spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/storage/WxCpInRedissonConfigStorageConfiguration.java
  10. 0 4
      spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml
  11. 5 8
      spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/config/storage/WxOpenInJedisConfigStorageConfiguration.java
  12. 7 10
      spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/config/storage/WxOpenInRedissonConfigStorageConfiguration.java
  13. 2 2
      spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenProperties.java
  14. 1 1
      spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/RedisProperties.java
  15. 4 0
      weixin-java-cp/pom.xml
  16. 183 0
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/AbstractWxCpInRedisConfigImpl.java
  17. 24 0
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpJedisConfigImpl.java
  18. 23 0
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpRedisTemplateConfigImpl.java
  19. 5 180
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpRedissonConfigImpl.java

+ 1 - 1
spring-boot-starters/wx-java-cp-spring-boot-starter/README.md

@@ -20,7 +20,7 @@
     wx.cp.aes-key = @aes-key
     wx.cp.agent-id = @agent-id
     # ConfigStorage 配置(选填)
-    wx.cp.config-storage.type=memory # memory 默认,目前只支持 memory 类型,可以自行扩展 redis 等类型
+    wx.cp.config-storage.type=memory # 配置类型: memory(默认), jedis, redisson, redistemplate
     # http 客户端配置(选填)
     wx.cp.config-storage.http-proxy-host=
     wx.cp.config-storage.http-proxy-port=

+ 12 - 0
spring-boot-starters/wx-java-cp-spring-boot-starter/pom.xml

@@ -18,6 +18,18 @@
       <artifactId>weixin-java-cp</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>redis.clients</groupId>
+      <artifactId>jedis</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.redisson</groupId>
+      <artifactId>redisson</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework.data</groupId>
+      <artifactId>spring-data-redis</artifactId>
+    </dependency>
   </dependencies>
 
   <build>

+ 7 - 1
spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/config/WxCpStorageAutoConfiguration.java

@@ -1,6 +1,9 @@
 package com.binarywang.spring.starter.wxjava.cp.config;
 
+import com.binarywang.spring.starter.wxjava.cp.storage.WxCpInJedisConfigStorageConfiguration;
 import com.binarywang.spring.starter.wxjava.cp.storage.WxCpInMemoryConfigStorageConfiguration;
+import com.binarywang.spring.starter.wxjava.cp.storage.WxCpInRedisTemplateConfigStorageConfiguration;
+import com.binarywang.spring.starter.wxjava.cp.storage.WxCpInRedissonConfigStorageConfiguration;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Import;
 
@@ -12,7 +15,10 @@ import org.springframework.context.annotation.Import;
  */
 @Configuration
 @Import({
-  WxCpInMemoryConfigStorageConfiguration.class
+  WxCpInMemoryConfigStorageConfiguration.class,
+  WxCpInJedisConfigStorageConfiguration.class,
+  WxCpInRedissonConfigStorageConfiguration.class,
+  WxCpInRedisTemplateConfigStorageConfiguration.class
 })
 public class WxCpStorageAutoConfiguration {
 }

+ 25 - 1
spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/properties/WxCpProperties.java

@@ -3,6 +3,7 @@ package com.binarywang.spring.starter.wxjava.cp.properties;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.NestedConfigurationProperty;
 
 import java.io.Serializable;
 
@@ -62,6 +63,17 @@ public class WxCpProperties {
     private StorageType type = StorageType.memory;
 
     /**
+     * 指定key前缀
+     */
+    private String keyPrefix = "wx:cp";
+
+    /**
+     * redis连接配置
+     */
+    @NestedConfigurationProperty
+    private WxCpRedisProperties redis = new WxCpRedisProperties();
+
+    /**
      * http代理主机
      */
     private String httpProxyHost;
@@ -104,6 +116,18 @@ public class WxCpProperties {
     /**
      * 内存
      */
-    memory
+    memory,
+    /**
+     * jedis
+     */
+    jedis,
+    /**
+     * redisson
+     */
+    redisson,
+    /**
+     * redistemplate
+     */
+    redistemplate
   }
 }

+ 46 - 0
spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/properties/WxCpRedisProperties.java

@@ -0,0 +1,46 @@
+package com.binarywang.spring.starter.wxjava.cp.properties;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * Redis配置.
+ *
+ * @author yl
+ * created on  2023/04/23
+ */
+@Data
+public class WxCpRedisProperties implements Serializable {
+  private static final long serialVersionUID = -5924815351660074401L;
+
+  /**
+   * 主机地址.
+   */
+  private String host;
+
+  /**
+   * 端口号.
+   */
+  private int port = 6379;
+
+  /**
+   * 密码.
+   */
+  private String password;
+
+  /**
+   * 超时.
+   */
+  private int timeout = 2000;
+
+  /**
+   * 数据库.
+   */
+  private int database = 0;
+
+  private Integer maxActive;
+  private Integer maxIdle;
+  private Integer maxWaitMillis;
+  private Integer minIdle;
+}

+ 2 - 4
spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/storage/AbstractWxCpConfigStorageConfiguration.java

@@ -15,8 +15,8 @@ public abstract class AbstractWxCpConfigStorageConfiguration {
   protected WxCpDefaultConfigImpl config(WxCpDefaultConfigImpl config, WxCpProperties properties) {
     String corpId = properties.getCorpId();
     String corpSecret = properties.getCorpSecret();
-    String token = properties.getToken();
     Integer agentId = properties.getAgentId();
+    String token = properties.getToken();
     String aesKey = properties.getAesKey();
     // 企业微信,私钥,会话存档路径
     String msgAuditPriKey = properties.getMsgAuditPriKey();
@@ -24,12 +24,10 @@ public abstract class AbstractWxCpConfigStorageConfiguration {
 
     config.setCorpId(corpId);
     config.setCorpSecret(corpSecret);
+    config.setAgentId(agentId);
     if (StringUtils.isNotBlank(token)) {
       config.setToken(token);
     }
-    if (agentId != null) {
-      config.setAgentId(agentId);
-    }
     if (StringUtils.isNotBlank(aesKey)) {
       config.setAesKey(aesKey);
     }

+ 74 - 0
spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/storage/WxCpInJedisConfigStorageConfiguration.java

@@ -0,0 +1,74 @@
+package com.binarywang.spring.starter.wxjava.cp.storage;
+
+import com.binarywang.spring.starter.wxjava.cp.properties.WxCpProperties;
+import com.binarywang.spring.starter.wxjava.cp.properties.WxCpRedisProperties;
+import lombok.RequiredArgsConstructor;
+import me.chanjar.weixin.cp.config.WxCpConfigStorage;
+import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
+import me.chanjar.weixin.cp.config.impl.WxCpJedisConfigImpl;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import redis.clients.jedis.JedisPool;
+import redis.clients.jedis.JedisPoolConfig;
+
+/**
+ * 自动装配基于 jedis 策略配置
+ *
+ * @author yl
+ * created on  2023/04/23
+ */
+@Configuration
+@ConditionalOnProperty(
+  prefix = WxCpProperties.PREFIX + ".config-storage", name = "type", havingValue = "jedis"
+)
+@RequiredArgsConstructor
+public class WxCpInJedisConfigStorageConfiguration extends AbstractWxCpConfigStorageConfiguration {
+  private final WxCpProperties wxCpProperties;
+  private final ApplicationContext applicationContext;
+
+  @Bean
+  @ConditionalOnMissingBean(WxCpConfigStorage.class)
+  public WxCpConfigStorage wxOpenConfigStorage() {
+    WxCpDefaultConfigImpl config = getConfigStorage();
+    return this.config(config, wxCpProperties);
+  }
+
+  private WxCpJedisConfigImpl getConfigStorage() {
+    WxCpRedisProperties wxCpRedisProperties = wxCpProperties.getConfigStorage().getRedis();
+    JedisPool jedisPool;
+    if (wxCpRedisProperties != null && StringUtils.isNotEmpty(wxCpRedisProperties.getHost())) {
+      jedisPool = getJedisPool();
+    } else {
+      jedisPool = applicationContext.getBean(JedisPool.class);
+    }
+    return new WxCpJedisConfigImpl(jedisPool, wxCpProperties.getConfigStorage().getKeyPrefix());
+  }
+
+  private JedisPool getJedisPool() {
+    WxCpProperties.ConfigStorage storage = wxCpProperties.getConfigStorage();
+    WxCpRedisProperties redis = storage.getRedis();
+
+    JedisPoolConfig config = new JedisPoolConfig();
+    if (redis.getMaxActive() != null) {
+      config.setMaxTotal(redis.getMaxActive());
+    }
+    if (redis.getMaxIdle() != null) {
+      config.setMaxIdle(redis.getMaxIdle());
+    }
+    if (redis.getMaxWaitMillis() != null) {
+      config.setMaxWaitMillis(redis.getMaxWaitMillis());
+    }
+    if (redis.getMinIdle() != null) {
+      config.setMinIdle(redis.getMinIdle());
+    }
+    config.setTestOnBorrow(true);
+    config.setTestWhileIdle(true);
+
+    return new JedisPool(config, redis.getHost(), redis.getPort(),
+      redis.getTimeout(), redis.getPassword(), redis.getDatabase());
+  }
+}

+ 41 - 0
spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/storage/WxCpInRedisTemplateConfigStorageConfiguration.java

@@ -0,0 +1,41 @@
+package com.binarywang.spring.starter.wxjava.cp.storage;
+
+import com.binarywang.spring.starter.wxjava.cp.properties.WxCpProperties;
+import lombok.RequiredArgsConstructor;
+import me.chanjar.weixin.cp.config.WxCpConfigStorage;
+import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
+import me.chanjar.weixin.cp.config.impl.WxCpRedisTemplateConfigImpl;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.core.StringRedisTemplate;
+
+/**
+ * 自动装配基于 redisTemplate 策略配置
+ *
+ * @author yl
+ * created on  2023/04/23
+ */
+@Configuration
+@ConditionalOnProperty(
+  prefix = WxCpProperties.PREFIX + ".config-storage", name = "type", havingValue = "redistemplate"
+)
+@RequiredArgsConstructor
+public class WxCpInRedisTemplateConfigStorageConfiguration extends AbstractWxCpConfigStorageConfiguration {
+  private final WxCpProperties wxCpProperties;
+  private final ApplicationContext applicationContext;
+
+  @Bean
+  @ConditionalOnMissingBean(WxCpConfigStorage.class)
+  public WxCpConfigStorage wxOpenConfigStorage() {
+    WxCpDefaultConfigImpl config = getConfigStorage();
+    return this.config(config, wxCpProperties);
+  }
+
+  private WxCpRedisTemplateConfigImpl getConfigStorage() {
+    StringRedisTemplate redisTemplate = applicationContext.getBean(StringRedisTemplate.class);
+    return new WxCpRedisTemplateConfigImpl(redisTemplate, wxCpProperties.getConfigStorage().getKeyPrefix());
+  }
+}

+ 65 - 0
spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/storage/WxCpInRedissonConfigStorageConfiguration.java

@@ -0,0 +1,65 @@
+package com.binarywang.spring.starter.wxjava.cp.storage;
+
+import com.binarywang.spring.starter.wxjava.cp.properties.WxCpProperties;
+import com.binarywang.spring.starter.wxjava.cp.properties.WxCpRedisProperties;
+import lombok.RequiredArgsConstructor;
+import me.chanjar.weixin.cp.config.WxCpConfigStorage;
+import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
+import me.chanjar.weixin.cp.config.impl.WxCpRedissonConfigImpl;
+import org.apache.commons.lang3.StringUtils;
+import org.redisson.Redisson;
+import org.redisson.api.RedissonClient;
+import org.redisson.config.Config;
+import org.redisson.config.TransportMode;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 自动装配基于 redisson 策略配置
+ *
+ * @author yl
+ * created on  2023/04/23
+ */
+@Configuration
+@ConditionalOnProperty(
+  prefix = WxCpProperties.PREFIX + ".config-storage", name = "type", havingValue = "redisson"
+)
+@RequiredArgsConstructor
+public class WxCpInRedissonConfigStorageConfiguration extends AbstractWxCpConfigStorageConfiguration {
+  private final WxCpProperties wxCpProperties;
+  private final ApplicationContext applicationContext;
+
+  @Bean
+  @ConditionalOnMissingBean(WxCpConfigStorage.class)
+  public WxCpConfigStorage wxOpenConfigStorage() {
+    WxCpDefaultConfigImpl config = getConfigStorage();
+    return this.config(config, wxCpProperties);
+  }
+
+  private WxCpRedissonConfigImpl getConfigStorage() {
+    WxCpRedisProperties redisProperties = wxCpProperties.getConfigStorage().getRedis();
+    RedissonClient redissonClient;
+    if (redisProperties != null && StringUtils.isNotEmpty(redisProperties.getHost())) {
+      redissonClient = getRedissonClient();
+    } else {
+      redissonClient = applicationContext.getBean(RedissonClient.class);
+    }
+    return new WxCpRedissonConfigImpl(redissonClient, wxCpProperties.getConfigStorage().getKeyPrefix());
+  }
+
+  private RedissonClient getRedissonClient() {
+    WxCpProperties.ConfigStorage storage = wxCpProperties.getConfigStorage();
+    WxCpRedisProperties redis = storage.getRedis();
+
+    Config config = new Config();
+    config.useSingleServer()
+      .setAddress("redis://" + redis.getHost() + ":" + redis.getPort())
+      .setDatabase(redis.getDatabase())
+      .setPassword(redis.getPassword());
+    config.setTransportMode(TransportMode.NIO);
+    return Redisson.create(config);
+  }
+}

+ 0 - 4
spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml

@@ -22,18 +22,14 @@
     <dependency>
       <groupId>redis.clients</groupId>
       <artifactId>jedis</artifactId>
-      <scope>provided</scope>
     </dependency>
     <dependency>
       <groupId>org.redisson</groupId>
       <artifactId>redisson</artifactId>
-      <scope>provided</scope>
     </dependency>
     <dependency>
       <groupId>org.springframework.data</groupId>
       <artifactId>spring-data-redis</artifactId>
-      <version>${spring.boot.version}</version>
-      <scope>provided</scope>
     </dependency>
   </dependencies>
 

+ 5 - 8
spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/config/storage/WxOpenInJedisConfigStorageConfiguration.java

@@ -1,10 +1,8 @@
 package com.binarywang.spring.starter.wxjava.open.config.storage;
 
-import com.binarywang.spring.starter.wxjava.open.properties.RedisProperties;
 import com.binarywang.spring.starter.wxjava.open.properties.WxOpenProperties;
+import com.binarywang.spring.starter.wxjava.open.properties.WxOpenRedisProperties;
 import lombok.RequiredArgsConstructor;
-import me.chanjar.weixin.common.redis.JedisWxRedisOps;
-import me.chanjar.weixin.common.redis.WxRedisOps;
 import me.chanjar.weixin.open.api.WxOpenConfigStorage;
 import me.chanjar.weixin.open.api.impl.WxOpenInMemoryConfigStorage;
 import me.chanjar.weixin.open.api.impl.WxOpenInRedisConfigStorage;
@@ -39,20 +37,19 @@ public class WxOpenInJedisConfigStorageConfiguration extends AbstractWxOpenConfi
   }
 
   private WxOpenInRedisConfigStorage getWxOpenInRedisConfigStorage() {
-    RedisProperties redisProperties = properties.getConfigStorage().getRedis();
+    WxOpenRedisProperties wxOpenRedisProperties = properties.getConfigStorage().getRedis();
     JedisPool jedisPool;
-    if (redisProperties != null && StringUtils.isNotEmpty(redisProperties.getHost())) {
+    if (wxOpenRedisProperties != null && StringUtils.isNotEmpty(wxOpenRedisProperties.getHost())) {
       jedisPool = getJedisPool();
     } else {
       jedisPool = applicationContext.getBean(JedisPool.class);
     }
-    WxRedisOps redisOps = new JedisWxRedisOps(jedisPool);
-    return new WxOpenInRedisConfigStorage(redisOps, properties.getConfigStorage().getKeyPrefix());
+    return new WxOpenInRedisConfigStorage(jedisPool, properties.getConfigStorage().getKeyPrefix());
   }
 
   private JedisPool getJedisPool() {
     WxOpenProperties.ConfigStorage storage = properties.getConfigStorage();
-    RedisProperties redis = storage.getRedis();
+    WxOpenRedisProperties redis = storage.getRedis();
 
     JedisPoolConfig config = new JedisPoolConfig();
     if (redis.getMaxActive() != null) {

+ 7 - 10
spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/config/storage/WxOpenInRedissonConfigStorageConfiguration.java

@@ -1,13 +1,11 @@
 package com.binarywang.spring.starter.wxjava.open.config.storage;
 
-import com.binarywang.spring.starter.wxjava.open.properties.RedisProperties;
 import com.binarywang.spring.starter.wxjava.open.properties.WxOpenProperties;
+import com.binarywang.spring.starter.wxjava.open.properties.WxOpenRedisProperties;
 import lombok.RequiredArgsConstructor;
-import me.chanjar.weixin.common.redis.RedissonWxRedisOps;
-import me.chanjar.weixin.common.redis.WxRedisOps;
 import me.chanjar.weixin.open.api.WxOpenConfigStorage;
 import me.chanjar.weixin.open.api.impl.WxOpenInMemoryConfigStorage;
-import me.chanjar.weixin.open.api.impl.WxOpenInRedisConfigStorage;
+import me.chanjar.weixin.open.api.impl.WxOpenInRedissonConfigStorage;
 import org.apache.commons.lang3.StringUtils;
 import org.redisson.Redisson;
 import org.redisson.api.RedissonClient;
@@ -40,21 +38,20 @@ public class WxOpenInRedissonConfigStorageConfiguration extends AbstractWxOpenCo
     return this.config(config, properties);
   }
 
-  private WxOpenInRedisConfigStorage getWxOpenInRedissonConfigStorage() {
-    RedisProperties redisProperties = properties.getConfigStorage().getRedis();
+  private WxOpenInRedissonConfigStorage getWxOpenInRedissonConfigStorage() {
+    WxOpenRedisProperties wxOpenRedisProperties = properties.getConfigStorage().getRedis();
     RedissonClient redissonClient;
-    if (redisProperties != null && StringUtils.isNotEmpty(redisProperties.getHost())) {
+    if (wxOpenRedisProperties != null && StringUtils.isNotEmpty(wxOpenRedisProperties.getHost())) {
       redissonClient = getRedissonClient();
     } else {
       redissonClient = applicationContext.getBean(RedissonClient.class);
     }
-    WxRedisOps redisOps = new RedissonWxRedisOps(redissonClient);
-    return new WxOpenInRedisConfigStorage(redisOps, properties.getConfigStorage().getKeyPrefix());
+    return new WxOpenInRedissonConfigStorage(redissonClient, properties.getConfigStorage().getKeyPrefix());
   }
 
   private RedissonClient getRedissonClient() {
     WxOpenProperties.ConfigStorage storage = properties.getConfigStorage();
-    RedisProperties redis = storage.getRedis();
+    WxOpenRedisProperties redis = storage.getRedis();
 
     Config config = new Config();
     config.useSingleServer()

+ 2 - 2
spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenProperties.java

@@ -58,13 +58,13 @@ public class WxOpenProperties {
     /**
      * 指定key前缀.
      */
-    private String keyPrefix = "wx";
+    private String keyPrefix = "wx:open";
 
     /**
      * redis连接配置.
      */
     @NestedConfigurationProperty
-    private RedisProperties redis = new RedisProperties();
+    private WxOpenRedisProperties redis = new WxOpenRedisProperties();
 
     /**
      * http客户端类型.

+ 1 - 1
spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/RedisProperties.java

@@ -10,7 +10,7 @@ import java.io.Serializable;
  * @author someone
  */
 @Data
-public class RedisProperties implements Serializable {
+public class WxOpenRedisProperties implements Serializable {
   private static final long serialVersionUID = -5924815351660074401L;
 
   /**

+ 4 - 0
weixin-java-cp/pom.xml

@@ -44,6 +44,10 @@
       <artifactId>redisson</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.springframework.data</groupId>
+      <artifactId>spring-data-redis</artifactId>
+    </dependency>
+    <dependency>
       <groupId>org.testng</groupId>
       <artifactId>testng</artifactId>
       <scope>test</scope>

+ 183 - 0
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/AbstractWxCpInRedisConfigImpl.java

@@ -0,0 +1,183 @@
+package me.chanjar.weixin.cp.config.impl;
+
+import lombok.NonNull;
+import me.chanjar.weixin.common.bean.WxAccessToken;
+import me.chanjar.weixin.common.redis.WxRedisOps;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+
+/**
+ * @author yl
+ * created on  2023/04/23
+ */
+public abstract class AbstractWxCpInRedisConfigImpl extends WxCpDefaultConfigImpl {
+  private static final long serialVersionUID = 7157341535439380615L;
+  /**
+   * The constant LOCK_KEY.
+   */
+  protected static final String LOCK_KEY = "wechat_cp_lock:";
+  /**
+   * The constant CP_ACCESS_TOKEN_KEY.
+   */
+  protected static final String CP_ACCESS_TOKEN_KEY = "wechat_cp_access_token_key:";
+  /**
+   * The constant CP_JSAPI_TICKET_KEY.
+   */
+  protected static final String CP_JSAPI_TICKET_KEY = "wechat_cp_jsapi_ticket_key:";
+  /**
+   * The constant CP_AGENT_JSAPI_TICKET_KEY.
+   */
+  protected static final String CP_AGENT_JSAPI_TICKET_KEY = "wechat_cp_agent_jsapi_ticket_key:";
+
+  /**
+   * redis 存储的 key 的前缀,可为空
+   */
+  protected String keyPrefix;
+  /**
+   * The Access token key.
+   */
+  protected String accessTokenKey;
+  /**
+   * The Jsapi ticket key.
+   */
+  protected String jsapiTicketKey;
+  /**
+   * The Agent jsapi ticket key.
+   */
+  protected String agentJsapiTicketKey;
+  /**
+   * The Lock key.
+   */
+  protected String lockKey;
+
+  private final WxRedisOps redisOps;
+
+  /**
+   * Instantiates a new Wx cp redis config.
+   *
+   * @param redisOps  the redis ops
+   * @param keyPrefix the key prefix
+   */
+  public AbstractWxCpInRedisConfigImpl(@NonNull WxRedisOps redisOps, String keyPrefix) {
+    this.redisOps = redisOps;
+    this.keyPrefix = keyPrefix;
+  }
+
+  /**
+   * 设置企业微信自研应用ID(整数),同时初始化相关的redis key,注意要先调用setCorpId,再调用setAgentId
+   *
+   * @param agentId 应用 agentId
+   */
+  @Override
+  public void setAgentId(Integer agentId) {
+    super.setAgentId(agentId);
+    String ukey;
+    if (agentId != null) {
+      ukey = getCorpId().concat(":").concat(String.valueOf(agentId));
+    } else {
+      ukey = getCorpId();
+    }
+    String prefix = StringUtils.isBlank(keyPrefix) ? "" :
+      (StringUtils.endsWith(keyPrefix, ":") ? keyPrefix : (keyPrefix + ":"));
+    lockKey = prefix + LOCK_KEY.concat(ukey);
+    accessTokenKey = prefix + CP_ACCESS_TOKEN_KEY.concat(ukey);
+    jsapiTicketKey = prefix + CP_JSAPI_TICKET_KEY.concat(ukey);
+    agentJsapiTicketKey = prefix + CP_AGENT_JSAPI_TICKET_KEY.concat(ukey);
+  }
+
+  /**
+   * Gets lock by key.
+   *
+   * @param key the key
+   * @return the lock by key
+   */
+  protected Lock getLockByKey(String key) {
+    return redisOps.getLock(key);
+  }
+
+  @Override
+  public Lock getAccessTokenLock() {
+    return getLockByKey(this.lockKey.concat(":").concat("accessToken"));
+  }
+
+  @Override
+  public Lock getAgentJsapiTicketLock() {
+    return getLockByKey(this.lockKey.concat(":").concat("agentJsapiTicket"));
+
+  }
+
+  @Override
+  public Lock getJsapiTicketLock() {
+    return getLockByKey(this.lockKey.concat(":").concat("jsapiTicket"));
+  }
+
+  @Override
+  public String getAccessToken() {
+    return redisOps.getValue(this.accessTokenKey);
+  }
+
+  @Override
+  public boolean isAccessTokenExpired() {
+    Long expire = redisOps.getExpire(this.accessTokenKey);
+    return expire == null || expire < 2;
+  }
+
+  @Override
+  public void updateAccessToken(WxAccessToken accessToken) {
+    redisOps.setValue(this.accessTokenKey, accessToken.getAccessToken(), accessToken.getExpiresIn(), TimeUnit.SECONDS);
+  }
+
+  @Override
+  public void updateAccessToken(String accessToken, int expiresInSeconds) {
+    redisOps.setValue(this.accessTokenKey, accessToken, expiresInSeconds, TimeUnit.SECONDS);
+  }
+
+  @Override
+  public void expireAccessToken() {
+    redisOps.expire(this.accessTokenKey, 0, TimeUnit.SECONDS);
+  }
+
+  @Override
+  public String getJsapiTicket() {
+    return redisOps.getValue(this.jsapiTicketKey);
+  }
+
+  @Override
+  public boolean isJsapiTicketExpired() {
+    Long expire = redisOps.getExpire(this.jsapiTicketKey);
+    return expire == null || expire < 2;
+  }
+
+  @Override
+  public void expireJsapiTicket() {
+    redisOps.expire(this.jsapiTicketKey, 0, TimeUnit.SECONDS);
+  }
+
+  @Override
+  public void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) {
+    redisOps.setValue(this.jsapiTicketKey, jsapiTicket, expiresInSeconds, TimeUnit.SECONDS);
+  }
+
+  @Override
+  public void expireAgentJsapiTicket() {
+    redisOps.expire(this.agentJsapiTicketKey, 0, TimeUnit.SECONDS);
+  }
+
+  @Override
+  public void updateAgentJsapiTicket(String agentJsapiTicket, int expiresInSeconds) {
+    redisOps.setValue(this.agentJsapiTicketKey, agentJsapiTicket, expiresInSeconds, TimeUnit.SECONDS);
+  }
+
+  @Override
+  public String getAgentJsapiTicket() {
+    return redisOps.getValue(this.agentJsapiTicketKey);
+  }
+
+  @Override
+  public boolean isAgentJsapiTicketExpired() {
+    Long expire = redisOps.getExpire(this.agentJsapiTicketKey);
+    return expire == null || expire < 2;
+  }
+}

+ 24 - 0
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpJedisConfigImpl.java

@@ -0,0 +1,24 @@
+package me.chanjar.weixin.cp.config.impl;
+
+import lombok.NonNull;
+import me.chanjar.weixin.common.redis.JedisWxRedisOps;
+import redis.clients.jedis.Jedis;
+import redis.clients.jedis.util.Pool;
+
+/**
+ * 基于 jdis 的实现
+ *
+ * @author yl
+ * created on  2023/04/23
+ */
+public class WxCpJedisConfigImpl extends AbstractWxCpInRedisConfigImpl {
+  private static final long serialVersionUID = -1869372247414407433L;
+
+  public WxCpJedisConfigImpl(Pool<Jedis> jedisPool) {
+    this(jedisPool, null);
+  }
+
+  public WxCpJedisConfigImpl(@NonNull Pool<Jedis> jedisPool, String keyPrefix) {
+    super(new JedisWxRedisOps(jedisPool), keyPrefix);
+  }
+}

+ 23 - 0
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpRedisTemplateConfigImpl.java

@@ -0,0 +1,23 @@
+package me.chanjar.weixin.cp.config.impl;
+
+import lombok.NonNull;
+import me.chanjar.weixin.common.redis.RedisTemplateWxRedisOps;
+import org.springframework.data.redis.core.StringRedisTemplate;
+
+/**
+ * 基于 RedisTemplate 的实现
+ *
+ * @author yl
+ * created on  2023/04/23
+ */
+public class WxCpRedisTemplateConfigImpl extends AbstractWxCpInRedisConfigImpl {
+  private static final long serialVersionUID = -1660004125413310620L;
+
+  public WxCpRedisTemplateConfigImpl(@NonNull StringRedisTemplate stringRedisTemplate) {
+    this(stringRedisTemplate, null);
+  }
+
+  public WxCpRedisTemplateConfigImpl(@NonNull StringRedisTemplate stringRedisTemplate, String keyPrefix) {
+    super(new RedisTemplateWxRedisOps(stringRedisTemplate), keyPrefix);
+  }
+}

+ 5 - 180
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpRedissonConfigImpl.java

@@ -1,198 +1,23 @@
 package me.chanjar.weixin.cp.config.impl;
 
 import lombok.NonNull;
-import me.chanjar.weixin.common.bean.WxAccessToken;
 import me.chanjar.weixin.common.redis.RedissonWxRedisOps;
-import me.chanjar.weixin.common.redis.WxRedisOps;
-import org.apache.commons.lang3.StringUtils;
 import org.redisson.api.RedissonClient;
 
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.Lock;
-
 /**
  * 基于Redisson的实现
  *
  * @author yuanqixun  created on  2020 /5/13
+ * @author yl
  */
-public class WxCpRedissonConfigImpl extends WxCpDefaultConfigImpl {
-  /**
-   * The constant LOCK_KEY.
-   */
-  protected static final String LOCK_KEY = "wechat_cp_lock:";
-  /**
-   * The constant CP_ACCESS_TOKEN_KEY.
-   */
-  protected static final String CP_ACCESS_TOKEN_KEY = "wechat_cp_access_token_key:";
-  /**
-   * The constant CP_JSAPI_TICKET_KEY.
-   */
-  protected static final String CP_JSAPI_TICKET_KEY = "wechat_cp_jsapi_ticket_key:";
-  /**
-   * The constant CP_AGENT_JSAPI_TICKET_KEY.
-   */
-  protected static final String CP_AGENT_JSAPI_TICKET_KEY = "wechat_cp_agent_jsapi_ticket_key:";
-  private final WxRedisOps redisOps;
-  /**
-   * redis 存储的 key 的前缀,可为空
-   */
-  protected String keyPrefix;
-  /**
-   * The Access token key.
-   */
-  protected String accessTokenKey;
-  /**
-   * The Jsapi ticket key.
-   */
-  protected String jsapiTicketKey;
-  /**
-   * The Agent jsapi ticket key.
-   */
-  protected String agentJsapiTicketKey;
-  /**
-   * The Lock key.
-   */
-  protected String lockKey;
-
-  /**
-   * Instantiates a new Wx cp redisson config.
-   *
-   * @param redissonClient the redisson client
-   * @param keyPrefix      the key prefix
-   */
-  public WxCpRedissonConfigImpl(@NonNull RedissonClient redissonClient, String keyPrefix) {
-    this(new RedissonWxRedisOps(redissonClient), keyPrefix);
-  }
+public class WxCpRedissonConfigImpl extends AbstractWxCpInRedisConfigImpl {
+  private static final long serialVersionUID = -5674792341070783967L;
 
-  /**
-   * Instantiates a new Wx cp redisson config.
-   *
-   * @param redissonClient the redisson client
-   */
   public WxCpRedissonConfigImpl(@NonNull RedissonClient redissonClient) {
     this(redissonClient, null);
   }
 
-  /**
-   * Instantiates a new Wx cp redisson config.
-   *
-   * @param redisOps  the redis ops
-   * @param keyPrefix the key prefix
-   */
-  public WxCpRedissonConfigImpl(@NonNull WxRedisOps redisOps, String keyPrefix) {
-    this.redisOps = redisOps;
-    this.keyPrefix = keyPrefix;
-  }
-
-  /**
-   * 设置企业微信自研应用ID(整数),同时初始化相关的redis key,注意要先调用setCorpId,再调用setAgentId
-   *
-   * @param agentId
-   */
-  @Override
-  public void setAgentId(Integer agentId) {
-    super.setAgentId(agentId);
-    String ukey = getCorpId().concat(":").concat(String.valueOf(agentId));
-    String prefix = StringUtils.isBlank(keyPrefix) ? "" :
-      (StringUtils.endsWith(keyPrefix, ":") ? keyPrefix : (keyPrefix + ":"));
-    lockKey = prefix + LOCK_KEY.concat(ukey);
-    accessTokenKey = prefix + CP_ACCESS_TOKEN_KEY.concat(ukey);
-    jsapiTicketKey = prefix + CP_JSAPI_TICKET_KEY.concat(ukey);
-    agentJsapiTicketKey = prefix + CP_AGENT_JSAPI_TICKET_KEY.concat(ukey);
-  }
-
-  /**
-   * Gets lock by key.
-   *
-   * @param key the key
-   * @return the lock by key
-   */
-  protected Lock getLockByKey(String key) {
-    return redisOps.getLock(key);
-  }
-
-  @Override
-  public Lock getAccessTokenLock() {
-    return getLockByKey(this.lockKey.concat(":").concat("accessToken"));
-  }
-
-  @Override
-  public Lock getAgentJsapiTicketLock() {
-    return getLockByKey(this.lockKey.concat(":").concat("agentJsapiTicket"));
-
-  }
-
-  @Override
-  public Lock getJsapiTicketLock() {
-    return getLockByKey(this.lockKey.concat(":").concat("jsapiTicket"));
-  }
-
-  @Override
-  public String getAccessToken() {
-    return redisOps.getValue(this.accessTokenKey);
-  }
-
-  @Override
-  public boolean isAccessTokenExpired() {
-    Long expire = redisOps.getExpire(this.accessTokenKey);
-    return expire == null || expire < 2;
-  }
-
-  @Override
-  public void updateAccessToken(WxAccessToken accessToken) {
-    redisOps.setValue(this.accessTokenKey, accessToken.getAccessToken(), accessToken.getExpiresIn(), TimeUnit.SECONDS);
-  }
-
-  @Override
-  public void updateAccessToken(String accessToken, int expiresInSeconds) {
-    redisOps.setValue(this.accessTokenKey, accessToken, expiresInSeconds, TimeUnit.SECONDS);
-  }
-
-  @Override
-  public void expireAccessToken() {
-    redisOps.expire(this.accessTokenKey, 0, TimeUnit.SECONDS);
-  }
-
-  @Override
-  public String getJsapiTicket() {
-    return redisOps.getValue(this.jsapiTicketKey);
-  }
-
-  @Override
-  public boolean isJsapiTicketExpired() {
-    Long expire = redisOps.getExpire(this.jsapiTicketKey);
-    return expire == null || expire < 2;
-  }
-
-  @Override
-  public void expireJsapiTicket() {
-    redisOps.expire(this.jsapiTicketKey, 0, TimeUnit.SECONDS);
-  }
-
-  @Override
-  public void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) {
-    redisOps.setValue(this.jsapiTicketKey, jsapiTicket, expiresInSeconds, TimeUnit.SECONDS);
-  }
-
-  @Override
-  public void expireAgentJsapiTicket() {
-    redisOps.expire(this.agentJsapiTicketKey, 0, TimeUnit.SECONDS);
-  }
-
-  @Override
-  public void updateAgentJsapiTicket(String agentJsapiTicket, int expiresInSeconds) {
-    redisOps.setValue(this.agentJsapiTicketKey, agentJsapiTicket, expiresInSeconds, TimeUnit.SECONDS);
-  }
-
-  @Override
-  public String getAgentJsapiTicket() {
-    return redisOps.getValue(this.agentJsapiTicketKey);
-  }
-
-  @Override
-  public boolean isAgentJsapiTicketExpired() {
-    Long expire = redisOps.getExpire(this.agentJsapiTicketKey);
-    return expire == null || expire < 2;
+  public WxCpRedissonConfigImpl(@NonNull RedissonClient redissonClient, String keyPrefix) {
+    super(new RedissonWxRedisOps(redissonClient), keyPrefix);
   }
-
 }