diff --git a/pom.xml b/pom.xml index dff83a69..07da003e 100644 --- a/pom.xml +++ b/pom.xml @@ -253,6 +253,14 @@ org.redisson redisson 3.12.0 + true + provided + + + org.springframework.data + spring-data-redis + 1.8.23.RELEASE + true provided diff --git a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml index 919702f8..9d446137 100644 --- a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml @@ -19,6 +19,17 @@ weixin-java-miniapp ${project.version} + + redis.clients + jedis + provided + + + org.springframework.data + spring-data-redis + ${spring.boot.version} + provided + diff --git a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/config/WxMaAutoConfiguration.java b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/config/WxMaAutoConfiguration.java index 109b398d..1c6d7865 100644 --- a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/config/WxMaAutoConfiguration.java +++ b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/config/WxMaAutoConfiguration.java @@ -4,15 +4,23 @@ import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; import cn.binarywang.wx.miniapp.config.WxMaConfig; import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl; +import cn.binarywang.wx.miniapp.config.impl.WxMaRedisBetterConfigImpl; import com.binarywang.spring.starter.wxjava.miniapp.properties.WxMaProperties; import lombok.AllArgsConstructor; +import me.chanjar.weixin.common.redis.JedisWxRedisOps; +import me.chanjar.weixin.common.redis.RedisTemplateWxRedisOps; +import me.chanjar.weixin.common.redis.WxRedisOps; import org.apache.commons.lang3.StringUtils; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.core.StringRedisTemplate; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; /** * 自动配置. @@ -26,7 +34,9 @@ import org.springframework.context.annotation.Configuration; @EnableConfigurationProperties(WxMaProperties.class) @ConditionalOnProperty(prefix = "wx.miniapp", value = "enabled", matchIfMissing = true) public class WxMaAutoConfiguration { - private WxMaProperties properties; + + private final WxMaProperties wxMaProperties; + private final ApplicationContext applicationContext; /** * 小程序service. @@ -35,16 +45,87 @@ public class WxMaAutoConfiguration { */ @Bean @ConditionalOnMissingBean(WxMaService.class) - public WxMaService service() { - WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl(); - config.setAppid(StringUtils.trimToNull(this.properties.getAppid())); - config.setSecret(StringUtils.trimToNull(this.properties.getSecret())); - config.setToken(StringUtils.trimToNull(this.properties.getToken())); - config.setAesKey(StringUtils.trimToNull(this.properties.getAesKey())); - config.setMsgDataFormat(StringUtils.trimToNull(this.properties.getMsgDataFormat())); - + public WxMaService service(WxMaConfig wxMaConfig) { final WxMaServiceImpl service = new WxMaServiceImpl(); - service.setWxMaConfig(config); + service.setWxMaConfig(wxMaConfig); return service; } + + @Bean + @ConditionalOnMissingBean(WxMaConfig.class) + public WxMaConfig wxMaConfig() { + WxMaProperties.StorageType type = wxMaProperties.getConfigStorage().getType(); + WxMaDefaultConfigImpl config; + if (type == WxMaProperties.StorageType.jedis) { + config = wxMaInJedisConfigStorage(); + } else if (type == WxMaProperties.StorageType.redistemplate) { + config = wxMaInRedisTemplateConfigStorage(); + } else { + config = wxMaInMemoryConfigStorage(); + } + + config.setAppid(StringUtils.trimToNull(this.wxMaProperties.getAppid())); + config.setSecret(StringUtils.trimToNull(this.wxMaProperties.getSecret())); + config.setToken(StringUtils.trimToNull(this.wxMaProperties.getToken())); + config.setAesKey(StringUtils.trimToNull(this.wxMaProperties.getAesKey())); + config.setMsgDataFormat(StringUtils.trimToNull(this.wxMaProperties.getMsgDataFormat())); + + WxMaProperties.ConfigStorage configStorageProperties = wxMaProperties.getConfigStorage(); + config.setHttpProxyHost(configStorageProperties.getHttpProxyHost()); + config.setHttpProxyUsername(configStorageProperties.getHttpProxyUsername()); + config.setHttpProxyPassword(configStorageProperties.getHttpProxyPassword()); + if (configStorageProperties.getHttpProxyPort() != null) { + config.setHttpProxyPort(configStorageProperties.getHttpProxyPort()); + } + return config; + } + + private WxMaDefaultConfigImpl wxMaInMemoryConfigStorage() { + WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl(); + return config; + } + + private WxMaDefaultConfigImpl wxMaInJedisConfigStorage() { + WxMaProperties.RedisProperties redisProperties = wxMaProperties.getConfigStorage().getRedis(); + JedisPool jedisPool; + if (redisProperties != null && StringUtils.isNotEmpty(redisProperties.getHost())) { + jedisPool = getJedisPool(); + } else { + jedisPool = applicationContext.getBean(JedisPool.class); + } + WxRedisOps redisOps = new JedisWxRedisOps(jedisPool); + WxMaRedisBetterConfigImpl wxMaRedisConfig = new WxMaRedisBetterConfigImpl(redisOps, wxMaProperties.getConfigStorage().getKeyPrefix()); + return wxMaRedisConfig; + } + + private WxMaDefaultConfigImpl wxMaInRedisTemplateConfigStorage() { + StringRedisTemplate redisTemplate = applicationContext.getBean(StringRedisTemplate.class); + WxRedisOps redisOps = new RedisTemplateWxRedisOps(redisTemplate); + WxMaRedisBetterConfigImpl wxMaRedisConfig = new WxMaRedisBetterConfigImpl(redisOps, wxMaProperties.getConfigStorage().getKeyPrefix()); + return wxMaRedisConfig; + } + + private JedisPool getJedisPool() { + WxMaProperties.ConfigStorage storage = wxMaProperties.getConfigStorage(); + WxMaProperties.RedisProperties 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()); + } } diff --git a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/properties/WxMaProperties.java b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/properties/WxMaProperties.java index 6477e61f..5af54dfe 100644 --- a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/properties/WxMaProperties.java +++ b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/miniapp/properties/WxMaProperties.java @@ -3,6 +3,8 @@ package com.binarywang.spring.starter.wxjava.miniapp.properties; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; +import java.io.Serializable; + /** * 属性配置类. * @@ -36,4 +38,112 @@ public class WxMaProperties { * 消息格式,XML或者JSON. */ private String msgDataFormat; + + /** + * 存储策略 + */ + private ConfigStorage configStorage = new ConfigStorage(); + + @Data + public static class ConfigStorage implements Serializable { + private static final long serialVersionUID = 4815731027000065434L; + + /** + * 存储类型. + */ + private StorageType type = StorageType.memory; + + /** + * 指定key前缀. + */ + private String keyPrefix = "wa"; + + /** + * redis连接配置. + */ + private RedisProperties redis; + + /** + * http客户端类型. + */ + private HttpClientType httpClientType = HttpClientType.httpclient; + + /** + * http代理主机. + */ + private String httpProxyHost; + + /** + * http代理端口. + */ + private Integer httpProxyPort; + + /** + * http代理用户名. + */ + private String httpProxyUsername; + + /** + * http代理密码. + */ + private String httpProxyPassword; + + } + + public enum StorageType { + /** + * 内存. + */ + memory, + /** + * redis(JedisClient). + */ + jedis, + /** + * redis(RedisTemplate). + */ + redistemplate + } + + public enum HttpClientType { + /** + * HttpClient. + */ + httpclient + } + + @Data + public static class RedisProperties 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; + } } diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/WxMpStorageAutoConfiguration.java b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/WxMpStorageAutoConfiguration.java index 5eb0ef5c..fc15e760 100644 --- a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/WxMpStorageAutoConfiguration.java +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/WxMpStorageAutoConfiguration.java @@ -1,13 +1,13 @@ package com.binarywang.spring.starter.wxjava.mp.config; -import com.binarywang.spring.starter.wxjava.mp.extend.RedisTemplateWxMpRedisOps; import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties; import lombok.RequiredArgsConstructor; +import me.chanjar.weixin.common.redis.JedisWxRedisOps; +import me.chanjar.weixin.common.redis.RedisTemplateWxRedisOps; +import me.chanjar.weixin.common.redis.WxRedisOps; import me.chanjar.weixin.mp.config.WxMpConfigStorage; import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; import me.chanjar.weixin.mp.config.impl.WxMpRedisConfigImpl; -import me.chanjar.weixin.mp.config.redis.JedisWxMpRedisOps; -import me.chanjar.weixin.mp.config.redis.WxMpRedisOps; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -65,7 +65,7 @@ public class WxMpStorageAutoConfiguration { } else { jedisPool = applicationContext.getBean(JedisPool.class); } - WxMpRedisOps redisOps = new JedisWxMpRedisOps(jedisPool); + WxRedisOps redisOps = new JedisWxRedisOps(jedisPool); WxMpRedisConfigImpl wxMpRedisConfig = new WxMpRedisConfigImpl(redisOps, wxMpProperties.getConfigStorage().getKeyPrefix()); setWxMpInfo(wxMpRedisConfig); return wxMpRedisConfig; @@ -73,7 +73,7 @@ public class WxMpStorageAutoConfiguration { private WxMpConfigStorage wxMpInRedisTemplateConfigStorage() { StringRedisTemplate redisTemplate = applicationContext.getBean(StringRedisTemplate.class); - WxMpRedisOps redisOps = new RedisTemplateWxMpRedisOps(redisTemplate); + WxRedisOps redisOps = new RedisTemplateWxRedisOps(redisTemplate); WxMpRedisConfigImpl wxMpRedisConfig = new WxMpRedisConfigImpl(redisOps, wxMpProperties.getConfigStorage().getKeyPrefix()); setWxMpInfo(wxMpRedisConfig); return wxMpRedisConfig; diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index 6ccd1919..7f85454e 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -122,11 +122,18 @@ redis.clients jedis - com.github.jedis-lock jedis-lock + + org.redisson + redisson + + + org.springframework.data + spring-data-redis + diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/redis/BaseWxMpRedisOps.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/redis/BaseWxRedisOps.java similarity index 84% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/redis/BaseWxMpRedisOps.java rename to weixin-java-common/src/main/java/me/chanjar/weixin/common/redis/BaseWxRedisOps.java index 8ec83641..17e992ab 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/redis/BaseWxMpRedisOps.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/redis/BaseWxRedisOps.java @@ -1,14 +1,14 @@ -package me.chanjar.weixin.mp.config.redis; +package me.chanjar.weixin.common.redis; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; /** - * 微信公众号redis操作基本类 + * 微信redis操作基本类 *

* 非内置实现redis相关操作, 请实现该类 */ -public class BaseWxMpRedisOps implements WxMpRedisOps { +public abstract class BaseWxRedisOps implements WxRedisOps { @Override public String getValue(String key) { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/redis/JedisWxMpRedisOps.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/redis/JedisWxRedisOps.java similarity index 82% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/redis/JedisWxMpRedisOps.java rename to weixin-java-common/src/main/java/me/chanjar/weixin/common/redis/JedisWxRedisOps.java index 0ba21bcd..0762e67d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/redis/JedisWxMpRedisOps.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/redis/JedisWxRedisOps.java @@ -1,6 +1,6 @@ -package me.chanjar.weixin.mp.config.redis; +package me.chanjar.weixin.common.redis; -import lombok.AllArgsConstructor; +import lombok.RequiredArgsConstructor; import me.chanjar.weixin.common.util.locks.JedisDistributedLock; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; @@ -8,13 +8,10 @@ import redis.clients.jedis.JedisPool; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; -/** - * Jedis实现相关操作 - */ -@AllArgsConstructor -public class JedisWxMpRedisOps implements WxMpRedisOps { +@RequiredArgsConstructor +public class JedisWxRedisOps implements WxRedisOps { - private JedisPool jedisPool; + private final JedisPool jedisPool; @Override public String getValue(String key) { diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/extend/RedisTemplateWxMpRedisOps.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/redis/RedisTemplateWxRedisOps.java similarity index 83% rename from spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/extend/RedisTemplateWxMpRedisOps.java rename to weixin-java-common/src/main/java/me/chanjar/weixin/common/redis/RedisTemplateWxRedisOps.java index 4939aba8..06870328 100644 --- a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/extend/RedisTemplateWxMpRedisOps.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/redis/RedisTemplateWxRedisOps.java @@ -1,7 +1,6 @@ -package com.binarywang.spring.starter.wxjava.mp.extend; +package me.chanjar.weixin.common.redis; import lombok.RequiredArgsConstructor; -import me.chanjar.weixin.mp.config.redis.BaseWxMpRedisOps; import org.springframework.data.redis.core.StringRedisTemplate; import java.util.concurrent.TimeUnit; @@ -9,7 +8,7 @@ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @RequiredArgsConstructor -public class RedisTemplateWxMpRedisOps extends BaseWxMpRedisOps { +public class RedisTemplateWxRedisOps implements WxRedisOps { private final StringRedisTemplate redisTemplate; diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/redis/RedissonWxRedisOps.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/redis/RedissonWxRedisOps.java new file mode 100644 index 00000000..e06db302 --- /dev/null +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/redis/RedissonWxRedisOps.java @@ -0,0 +1,39 @@ +package me.chanjar.weixin.common.redis; + +import lombok.RequiredArgsConstructor; +import org.redisson.api.RedissonClient; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; + +@RequiredArgsConstructor +public class RedissonWxRedisOps implements WxRedisOps { + + private final RedissonClient redissonClient; + + @Override + public String getValue(String key) { + Object value = redissonClient.getBucket(key).get(); + return value == null ? null : value.toString(); + } + + @Override + public void setValue(String key, String value, int expire, TimeUnit timeUnit) { + redissonClient.getBucket(key).set(value, expire, timeUnit); + } + + @Override + public Long getExpire(String key) { + return redissonClient.getBucket(key).remainTimeToLive(); + } + + @Override + public void expire(String key, int expire, TimeUnit timeUnit) { + redissonClient.getBucket(key).expire(expire, timeUnit); + } + + @Override + public Lock getLock(String key) { + return redissonClient.getLock(key); + } +} diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/redis/WxRedisOps.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/redis/WxRedisOps.java new file mode 100644 index 00000000..5489165e --- /dev/null +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/redis/WxRedisOps.java @@ -0,0 +1,27 @@ +package me.chanjar.weixin.common.redis; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; + +/** + * 微信Redis相关操作 + *

+ * 该接口不承诺稳定, 外部实现请继承{@link BaseWxRedisOps} + * + * @see BaseWxRedisOps 实现需要继承该类 + * @see JedisWxRedisOps jedis实现 + * @see RedissonWxRedisOps redisson实现 + * @see RedisTemplateWxRedisOps redisTemplate实现 + */ +public interface WxRedisOps { + + String getValue(String key); + + void setValue(String key, String value, int expire, TimeUnit timeUnit); + + Long getExpire(String key); + + void expire(String key, int expire, TimeUnit timeUnit); + + Lock getLock(String key); +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/WxMaDefaultConfigImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/WxMaDefaultConfigImpl.java index b75fa711..94e09bc5 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/WxMaDefaultConfigImpl.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/WxMaDefaultConfigImpl.java @@ -46,8 +46,8 @@ public class WxMaDefaultConfigImpl implements WxMaConfig { */ private volatile String cardApiTicket; private volatile long cardApiTicketExpiresTime; - private Lock jsapiTicketLock = new ReentrantLock(); - private Lock cardApiTicketLock = new ReentrantLock(); + protected volatile Lock jsapiTicketLock = new ReentrantLock(); + protected volatile Lock cardApiTicketLock = new ReentrantLock(); private volatile ApacheHttpClientBuilder apacheHttpClientBuilder; /** diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/WxMaRedisBetterConfigImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/WxMaRedisBetterConfigImpl.java new file mode 100644 index 00000000..e53ed198 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/WxMaRedisBetterConfigImpl.java @@ -0,0 +1,130 @@ +package cn.binarywang.wx.miniapp.config.impl; + +import cn.binarywang.wx.miniapp.constant.TicketType; +import me.chanjar.weixin.common.redis.JedisWxRedisOps; +import me.chanjar.weixin.common.redis.WxRedisOps; +import redis.clients.jedis.JedisPool; + +import java.util.concurrent.TimeUnit; + +/** + * 基于redis存储的微信小程序配置类 + */ +public class WxMaRedisBetterConfigImpl extends WxMaDefaultConfigImpl { + private static final String ACCESS_TOKEN_KEY_TPL = "%s:access_token:%s"; + private static final String TICKET_KEY_TPL = "%s:ticket:key:%s:%s"; + private static final String LOCK_KEY_TPL = "%s:lock:%s:"; + + private final WxRedisOps redisOps; + private final String keyPrefix; + + private volatile String accessTokenKey; + private volatile String lockKey; + + public WxMaRedisBetterConfigImpl(JedisPool jedisPool) { + this(new JedisWxRedisOps(jedisPool), "wa"); + } + + public WxMaRedisBetterConfigImpl(WxRedisOps redisOps, String keyPrefix) { + this.redisOps = redisOps; + this.keyPrefix = keyPrefix; + } + + @Override + public void setAppid(String appId) { + super.setAppid(appId); + this.accessTokenKey = String.format(ACCESS_TOKEN_KEY_TPL, this.keyPrefix, appId); + this.lockKey = String.format(LOCK_KEY_TPL, this.keyPrefix, appId); + super.accessTokenLock = this.redisOps.getLock(lockKey.concat("accessTokenLock")); + super.jsapiTicketLock = this.redisOps.getLock(lockKey.concat("jsapiTicketLock")); + super.cardApiTicketLock = this.redisOps.getLock(lockKey.concat("cardApiTicketLock")); + } + + //------------------------------------------------------------------------ + // token相关 + //------------------------------------------------------------------------ + @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 synchronized void updateAccessToken(String accessToken, int expiresInSeconds) { + redisOps.setValue(this.accessTokenKey, accessToken, expiresInSeconds - 200, TimeUnit.SECONDS); + } + + @Override + public void expireAccessToken() { + redisOps.expire(this.accessTokenKey, 0, TimeUnit.SECONDS); + } + + //------------------------------------------------------------------------ + // ticket相关 + //------------------------------------------------------------------------ + @Override + public String getJsapiTicket() { + return doGetTicket(TicketType.JSAPI); + } + + @Override + public boolean isJsapiTicketExpired() { + return doIsTicketExpired(TicketType.JSAPI); + } + + @Override + public void expireJsapiTicket() { + doExpireTicket(TicketType.JSAPI); + } + + @Override + public synchronized void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) { + doUpdateTicket(TicketType.JSAPI, jsapiTicket, expiresInSeconds); + } + + @Override + public String getCardApiTicket() { + return doGetTicket(TicketType.WX_CARD); + } + + @Override + public boolean isCardApiTicketExpired() { + return doIsTicketExpired(TicketType.WX_CARD); + } + + @Override + public void expireCardApiTicket() { + doExpireTicket(TicketType.WX_CARD); + } + + @Override + public synchronized void updateCardApiTicket(String cardApiTicket, int expiresInSeconds) { + doUpdateTicket(TicketType.WX_CARD, cardApiTicket, expiresInSeconds); + } + + private String getTicketRedisKey(TicketType type) { + return String.format(TICKET_KEY_TPL, this.keyPrefix, this.appid, type.getCode()); + } + + private String doGetTicket(TicketType type) { + return redisOps.getValue(this.getTicketRedisKey(type)); + } + + private boolean doIsTicketExpired(TicketType type) { + return redisOps.getExpire(this.getTicketRedisKey(type)) < 2; + } + + private void doUpdateTicket(TicketType type, String ticket, int expiresInSeconds) { + redisOps.setValue(this.getTicketRedisKey(type), ticket, expiresInSeconds - 200, TimeUnit.SECONDS); + } + + private void doExpireTicket(TicketType type) { + redisOps.expire(this.getTicketRedisKey(type), 0, TimeUnit.SECONDS); + } + +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/TicketType.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/TicketType.java new file mode 100644 index 00000000..e8b07de0 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/TicketType.java @@ -0,0 +1,30 @@ +package cn.binarywang.wx.miniapp.constant; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + *

+ * ticket类型枚举
+ * Created by Binary Wang on 2018/11/18.
+ * 
+ * + * @author Binary Wang + */ +@Getter +@RequiredArgsConstructor +public enum TicketType { + /** + * jsapi + */ + JSAPI("jsapi"), + /** + * 微信卡券 + */ + WX_CARD("wx_card"); + /** + * type代码 + */ + private final String code; + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/impl/WxMpRedisConfigImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/impl/WxMpRedisConfigImpl.java index cbf5eaf3..8460d464 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/impl/WxMpRedisConfigImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/impl/WxMpRedisConfigImpl.java @@ -1,8 +1,8 @@ package me.chanjar.weixin.mp.config.impl; import lombok.Data; -import me.chanjar.weixin.mp.config.redis.JedisWxMpRedisOps; -import me.chanjar.weixin.mp.config.redis.WxMpRedisOps; +import me.chanjar.weixin.common.redis.JedisWxRedisOps; +import me.chanjar.weixin.common.redis.WxRedisOps; import me.chanjar.weixin.mp.enums.TicketType; import redis.clients.jedis.JedisPool; @@ -22,22 +22,22 @@ import java.util.concurrent.TimeUnit; @SuppressWarnings("hiding") public class WxMpRedisConfigImpl extends WxMpDefaultConfigImpl { private static final long serialVersionUID = -988502871997239733L; - + private static final String ACCESS_TOKEN_KEY_TPL = "%s:access_token:%s"; private static final String TICKET_KEY_TPL = "%s:ticket:key:%s:%s"; private static final String LOCK_KEY_TPL = "%s:lock:%s:"; - private final WxMpRedisOps redisOps; + private final WxRedisOps redisOps; private final String keyPrefix; private String accessTokenKey; private String lockKey; public WxMpRedisConfigImpl(JedisPool jedisPool) { - this(new JedisWxMpRedisOps(jedisPool), "wx"); + this(new JedisWxRedisOps(jedisPool), "wx"); } - public WxMpRedisConfigImpl(WxMpRedisOps redisOps, String keyPrefix) { + public WxMpRedisConfigImpl(WxRedisOps redisOps, String keyPrefix) { this.redisOps = redisOps; this.keyPrefix = keyPrefix; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/redis/WxMpRedisOps.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/redis/WxMpRedisOps.java deleted file mode 100644 index d57d037c..00000000 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/redis/WxMpRedisOps.java +++ /dev/null @@ -1,25 +0,0 @@ -package me.chanjar.weixin.mp.config.redis; - -import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.Lock; - -/** - * 微信公众号Redis相关操作 - *

- * 该接口不承诺稳定, 外部实现请继承{@link BaseWxMpRedisOps} - * - * @see BaseWxMpRedisOps 实现需要继承该类 - * @see JedisWxMpRedisOps jedis实现 - */ -public interface WxMpRedisOps { - - String getValue(String key); - - void setValue(String key, String value, int expire, TimeUnit timeUnit); - - Long getExpire(String key); - - void expire(String key, int expire, TimeUnit timeUnit); - - Lock getLock(String key); -}