From 2e75e465c7a67a69a1096907e2556192945ad0b6 Mon Sep 17 00:00:00 2001 From: Mario Luo Date: Mon, 13 Apr 2020 20:13:03 +0800 Subject: [PATCH] =?UTF-8?q?:art:=20#1503=20=E5=BE=AE=E4=BF=A1=E5=85=AC?= =?UTF-8?q?=E4=BC=97=E5=8F=B7=E6=A8=A1=E5=9D=97=E6=8F=90=E5=8F=96redis?= =?UTF-8?q?=E6=8A=BD=E8=B1=A1=E5=B1=82=E3=80=81=E6=94=AF=E6=8C=81key?= =?UTF-8?q?=E5=89=8D=E7=BC=80=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mp/config/impl/WxMpRedisConfigImpl.java | 75 ++++++++----------- .../mp/config/redis/BaseWxMpRedisOps.java | 37 +++++++++ .../mp/config/redis/JedisWxMpRedisOps.java | 51 +++++++++++++ .../weixin/mp/config/redis/WxMpRedisOps.java | 25 +++++++ 4 files changed, 145 insertions(+), 43 deletions(-) create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/redis/BaseWxMpRedisOps.java create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/redis/JedisWxMpRedisOps.java create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/redis/WxMpRedisOps.java 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 8c61c9b2..4b33f852 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,12 +1,12 @@ package me.chanjar.weixin.mp.config.impl; -import me.chanjar.weixin.common.util.locks.JedisDistributedLock; +import com.sun.istack.internal.NotNull; +import me.chanjar.weixin.mp.config.redis.JedisWxMpRedisOps; +import me.chanjar.weixin.mp.config.redis.WxMpRedisOps; import me.chanjar.weixin.mp.enums.TicketType; -import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.TimeUnit; /** * 基于Redis的微信配置provider. @@ -20,19 +20,23 @@ import java.util.concurrent.locks.ReentrantLock; */ @SuppressWarnings("hiding") public class WxMpRedisConfigImpl extends WxMpDefaultConfigImpl { - private static final String ACCESS_TOKEN_KEY = "wx:access_token:"; - private static final String LOCK_KEY = "wx:lock:"; + 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 JedisPool jedisPool; + private final WxMpRedisOps redisOps; + private final String keyPrefix; private String accessTokenKey; private String lockKey; - public WxMpRedisConfigImpl(JedisPool jedisPool) { - this.jedisPool = jedisPool; + public WxMpRedisConfigImpl(@NotNull JedisPool jedisPool) { + this(new JedisWxMpRedisOps(jedisPool), "wx"); + } + + public WxMpRedisConfigImpl(@NotNull WxMpRedisOps redisOps, @NotNull String keyPrefix) { + this.redisOps = redisOps; + this.keyPrefix = keyPrefix; } /** @@ -41,72 +45,57 @@ public class WxMpRedisConfigImpl extends WxMpDefaultConfigImpl { @Override public void setAppId(String appId) { super.setAppId(appId); - this.accessTokenKey = ACCESS_TOKEN_KEY.concat(appId); - this.lockKey = ACCESS_TOKEN_KEY.concat(appId).concat(":"); - accessTokenLock = new JedisDistributedLock(jedisPool, lockKey.concat("accessTokenLock")); - jsapiTicketLock = new JedisDistributedLock(jedisPool, lockKey.concat("jsapiTicketLock")); - sdkTicketLock = new JedisDistributedLock(jedisPool, lockKey.concat("sdkTicketLock")); - cardApiTicketLock = new JedisDistributedLock(jedisPool, lockKey.concat("cardApiTicketLock")); + this.accessTokenKey = String.format(ACCESS_TOKEN_KEY_TPL, this.keyPrefix, appId); + this.lockKey = String.format(LOCK_KEY_TPL, this.keyPrefix, appId); + accessTokenLock = this.redisOps.getLock(lockKey.concat("accessTokenLock")); + jsapiTicketLock = this.redisOps.getLock(lockKey.concat("jsapiTicketLock")); + sdkTicketLock = this.redisOps.getLock(lockKey.concat("sdkTicketLock")); + cardApiTicketLock = this.redisOps.getLock(lockKey.concat("cardApiTicketLock")); } private String getTicketRedisKey(TicketType type) { - return String.format("wx:ticket:key:%s:%s", this.appId, type.getCode()); + return String.format(TICKET_KEY_TPL, this.keyPrefix, appId, type.getCode()); } @Override public String getAccessToken() { - try (Jedis jedis = this.jedisPool.getResource()) { - return jedis.get(this.accessTokenKey); - } + return redisOps.getValue(this.accessTokenKey); } @Override public boolean isAccessTokenExpired() { - try (Jedis jedis = this.jedisPool.getResource()) { - return jedis.ttl(accessTokenKey) < 2; - } + Long expire = redisOps.getExpire(this.accessTokenKey); + return expire == null || expire < 2; } @Override public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) { - try (Jedis jedis = this.jedisPool.getResource()) { - jedis.setex(this.accessTokenKey, expiresInSeconds - 200, accessToken); - } + redisOps.setValue(this.accessTokenKey, accessToken, expiresInSeconds - 200, TimeUnit.SECONDS); } @Override public void expireAccessToken() { - try (Jedis jedis = this.jedisPool.getResource()) { - jedis.expire(this.accessTokenKey, 0); - } + redisOps.expire(this.accessTokenKey, 0, TimeUnit.SECONDS); } @Override public String getTicket(TicketType type) { - try (Jedis jedis = this.jedisPool.getResource()) { - return jedis.get(this.getTicketRedisKey(type)); - } + return redisOps.getValue(this.getTicketRedisKey(type)); } @Override public boolean isTicketExpired(TicketType type) { - try (Jedis jedis = this.jedisPool.getResource()) { - return jedis.ttl(this.getTicketRedisKey(type)) < 2; - } + return redisOps.getExpire(this.getTicketRedisKey(type)) < 2; } @Override public synchronized void updateTicket(TicketType type, String jsapiTicket, int expiresInSeconds) { - try (Jedis jedis = this.jedisPool.getResource()) { - jedis.setex(this.getTicketRedisKey(type), expiresInSeconds - 200, jsapiTicket); - } + redisOps.setValue(this.getTicketRedisKey(type), jsapiTicket, expiresInSeconds - 200, TimeUnit.SECONDS); } @Override public void expireTicket(TicketType type) { - try (Jedis jedis = this.jedisPool.getResource()) { - jedis.expire(this.getTicketRedisKey(type), 0); - } + redisOps.expire(this.getTicketRedisKey(type), 0, TimeUnit.SECONDS); } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/redis/BaseWxMpRedisOps.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/redis/BaseWxMpRedisOps.java new file mode 100644 index 00000000..8ec83641 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/redis/BaseWxMpRedisOps.java @@ -0,0 +1,37 @@ +package me.chanjar.weixin.mp.config.redis; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; + +/** + * 微信公众号redis操作基本类 + *

+ * 非内置实现redis相关操作, 请实现该类 + */ +public class BaseWxMpRedisOps implements WxMpRedisOps { + + @Override + public String getValue(String key) { + throw new UnsupportedOperationException(); + } + + @Override + public void setValue(String key, String value, int expire, TimeUnit timeUnit) { + throw new UnsupportedOperationException(); + } + + @Override + public Long getExpire(String key) { + throw new UnsupportedOperationException(); + } + + @Override + public void expire(String key, int expire, TimeUnit timeUnit) { + throw new UnsupportedOperationException(); + } + + @Override + public Lock getLock(String key) { + throw new UnsupportedOperationException(); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/redis/JedisWxMpRedisOps.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/redis/JedisWxMpRedisOps.java new file mode 100644 index 00000000..0ba21bcd --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/redis/JedisWxMpRedisOps.java @@ -0,0 +1,51 @@ +package me.chanjar.weixin.mp.config.redis; + +import lombok.AllArgsConstructor; +import me.chanjar.weixin.common.util.locks.JedisDistributedLock; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; + +/** + * Jedis实现相关操作 + */ +@AllArgsConstructor +public class JedisWxMpRedisOps implements WxMpRedisOps { + + private JedisPool jedisPool; + + @Override + public String getValue(String key) { + try (Jedis jedis = this.jedisPool.getResource()) { + return jedis.get(key); + } + } + + @Override + public void setValue(String key, String value, int expire, TimeUnit timeUnit) { + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.psetex(key, timeUnit.toMillis(expire), value); + } + } + + @Override + public Long getExpire(String key) { + try (Jedis jedis = this.jedisPool.getResource()) { + return jedis.ttl(key); + } + } + + @Override + public void expire(String key, int expire, TimeUnit timeUnit) { + try (Jedis jedis = this.jedisPool.getResource()) { + jedis.pexpire(key, timeUnit.toMillis(expire)); + } + } + + @Override + public Lock getLock(String key) { + return new JedisDistributedLock(jedisPool, key); + } +} 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 new file mode 100644 index 00000000..d57d037c --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/config/redis/WxMpRedisOps.java @@ -0,0 +1,25 @@ +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); +}