Skip to content

修改 Redis 配置实现类以实现选择数据库及密码认证功能 #1314

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,280 @@
package cn.binarywang.wx.miniapp.config.impl;

import com.github.jedis.lock.JedisLock;
import redis.clients.jedis.Jedis;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

/**
* @author <a href="https://github.com/winter4666">winter</a>
*/
public abstract class AbstractWxMaRedisConfig extends WxMaDefaultConfigImpl {

public interface JedisConfig {
Jedis config(Jedis jedis);
}

private static final String ACCESS_TOKEN = "accessToken";
private static final String JSAPI_TICKET = "jsapiTicket";
private static final String CARD_API_TICKET = "cardApiTicket";

private static final String HASH_VALUE_FIELD = "value";
private static final String HASH_EXPIRE_FIELD = "expire";

/**
* Redis Key 的前缀,默认为 maConfig
*/
private String redisKeyPrefix = "maConfig";

/**
* 微信小程序唯一id,用于拼接存储到redis时的key,防止key重复.
*/
private String maId;

private Lock accessTokenLock;
private Lock jsapiTicketLock;
private Lock cardApiTicketLock;

/**
* 临时文件目录.
*/
protected volatile File tmpDirFile;

/**
* 对从 JedisPool.getResource() 获取到的每个 Jedis 实例进行配置
*/
private JedisConfig jedisConfig;

protected abstract Jedis getJedis();

private Jedis getConfiguredJedis() {
Jedis jedis = getJedis();
if (jedisConfig != null) {
return jedisConfig.config(jedis);
} else {
return jedis;
}
}

private String getRedisKey(String key) {
StringBuilder redisKey = new StringBuilder(redisKeyPrefix).append(":");
if (maId == null) {
return redisKey.append(key).toString();
} else {
return redisKey.append(maId).append(":").append(key).toString();
}
}

private String getValueFromRedis(String key) {
try (Jedis jedis = getConfiguredJedis()) {
return jedis.hget(getRedisKey(key), HASH_VALUE_FIELD);
}
}

private void setValueToRedis(String key, long expiresTime, String value) {
try (Jedis jedis = getConfiguredJedis()) {
Map<String, String> hash = new HashMap<String, String>();
hash.put(HASH_VALUE_FIELD, value);
hash.put(HASH_EXPIRE_FIELD, String.valueOf(expiresTime));
jedis.hmset(getRedisKey(key), hash);
}
}

private long getExpireFromRedis(String key) {
try (Jedis jedis = getConfiguredJedis()) {
String expire = jedis.hget(getRedisKey(key), HASH_EXPIRE_FIELD);
return expire == null ? 0 : Long.parseLong(expire);
}
}

private void setExpire(String key, long expiresTime) {
try (Jedis jedis = getConfiguredJedis()) {
jedis.hset(getRedisKey(key), HASH_EXPIRE_FIELD, String.valueOf(expiresTime));
}
}

public void setRedisKeyPrefix(String redisKeyPrefix) {
this.redisKeyPrefix = redisKeyPrefix;
}

public void setJedisConfig(JedisConfig jedisConfig) {
this.jedisConfig = jedisConfig;
}

public void setMaId(String maId) {
this.maId = maId;
}

@Override
public String getAccessToken() {
return getValueFromRedis(ACCESS_TOKEN);
}

@Override
public Lock getAccessTokenLock() {
if (accessTokenLock == null) {
synchronized (this) {
if (accessTokenLock == null) {
accessTokenLock = new DistributedLock(getRedisKey("accessTokenLock"));
}
}
}
return accessTokenLock;
}

@Override
public boolean isAccessTokenExpired() {
return isExpired(getExpireFromRedis(ACCESS_TOKEN));
}

@Override
public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) {
setValueToRedis(ACCESS_TOKEN, expiresAheadInMillis(expiresInSeconds), accessToken);
}

@Override
public String getJsapiTicket() {
return getValueFromRedis(JSAPI_TICKET);
}

@Override
public Lock getJsapiTicketLock() {
if (jsapiTicketLock == null) {
synchronized (this) {
if (jsapiTicketLock == null) {
jsapiTicketLock = new DistributedLock(getRedisKey("jsapiTicketLock"));
}
}
}
return jsapiTicketLock;
}

@Override
public boolean isJsapiTicketExpired() {
return isExpired(getExpireFromRedis(JSAPI_TICKET));
}

@Override
public void expireJsapiTicket() {
setExpire(JSAPI_TICKET, 0);
}

@Override
public void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) {
setValueToRedis(JSAPI_TICKET, expiresAheadInMillis(expiresInSeconds), jsapiTicket);
}


@Override
public String getCardApiTicket() {
return getValueFromRedis(CARD_API_TICKET);
}

@Override
public Lock getCardApiTicketLock() {
if (cardApiTicketLock == null) {
synchronized (this) {
if (cardApiTicketLock == null) {
cardApiTicketLock = new DistributedLock(getRedisKey("cardApiTicketLock"));
}
}
}
return cardApiTicketLock;
}

@Override
public boolean isCardApiTicketExpired() {
return isExpired(getExpireFromRedis(CARD_API_TICKET));
}

@Override
public void expireCardApiTicket() {
setExpire(CARD_API_TICKET, 0);
}

@Override
public void updateCardApiTicket(String cardApiTicket, int expiresInSeconds) {
setValueToRedis(CARD_API_TICKET, expiresAheadInMillis(expiresInSeconds), cardApiTicket);
}

@Override
public void expireAccessToken() {
setExpiresTime(0);
}

@Override
public long getExpiresTime() {
return getExpireFromRedis(ACCESS_TOKEN);
}

@Override
public void setExpiresTime(long expiresTime) {
setExpire(ACCESS_TOKEN, expiresTime);
}

/**
* 基于redis的简单分布式锁.
*/
private class DistributedLock implements Lock {

private JedisLock lock;

private DistributedLock(String key) {
this.lock = new JedisLock(getRedisKey(key));
}

@Override
public void lock() {
try (Jedis jedis = getConfiguredJedis()) {
if (!lock.acquire(jedis)) {
throw new RuntimeException("acquire timeouted");
}
} catch (InterruptedException e) {
throw new RuntimeException("lock failed", e);
}
}

@Override
public void lockInterruptibly() throws InterruptedException {
try (Jedis jedis = getConfiguredJedis()) {
if (!lock.acquire(jedis)) {
throw new RuntimeException("acquire timeouted");
}
}
}

@Override
public boolean tryLock() {
try (Jedis jedis = getConfiguredJedis()) {
return lock.acquire(jedis);
} catch (InterruptedException e) {
throw new RuntimeException("lock failed", e);
}
}

@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
try (Jedis jedis = getConfiguredJedis()) {
return lock.acquire(jedis);
}
}

@Override
public void unlock() {
try (Jedis jedis = getConfiguredJedis()) {
lock.release(jedis);
}
}

@Override
public Condition newCondition() {
throw new RuntimeException("unsupported method");
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,20 @@ public class WxMaDefaultConfigImpl implements WxMaConfig {

private volatile ApacheHttpClientBuilder apacheHttpClientBuilder;

/**
* 会过期的数据提前过期时间,默认预留200秒的时间
*/
protected long expiresAheadInMillis(int expiresInSeconds) {
return System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
}

/**
* 判断 expiresTime 是否已经过期
*/
protected boolean isExpired(long expiresTime) {
return System.currentTimeMillis() > expiresTime;
}

@Override
public String getAccessToken() {
return this.accessToken;
Expand All @@ -68,7 +82,7 @@ public void setAccessTokenLock(Lock accessTokenLock) {

@Override
public boolean isAccessTokenExpired() {
return System.currentTimeMillis() > this.expiresTime;
return isExpired(this.expiresTime);
}

@Override
Expand All @@ -78,8 +92,8 @@ public synchronized void updateAccessToken(WxAccessToken accessToken) {

@Override
public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) {
this.accessToken = accessToken;
this.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
setAccessToken(accessToken);
setExpiresTime(expiresAheadInMillis(expiresInSeconds));
}

@Override
Expand All @@ -94,7 +108,7 @@ public Lock getJsapiTicketLock() {

@Override
public boolean isJsapiTicketExpired() {
return System.currentTimeMillis() > this.jsapiTicketExpiresTime;
return isExpired(this.jsapiTicketExpiresTime);
}

@Override
Expand All @@ -105,8 +119,7 @@ public void expireJsapiTicket() {
@Override
public void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) {
this.jsapiTicket = jsapiTicket;
// 预留200秒的时间
this.jsapiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
this.jsapiTicketExpiresTime = expiresAheadInMillis(expiresInSeconds);
}


Expand All @@ -122,7 +135,7 @@ public Lock getCardApiTicketLock() {

@Override
public boolean isCardApiTicketExpired() {
return System.currentTimeMillis() > this.cardApiTicketExpiresTime;
return isExpired(this.cardApiTicketExpiresTime);
}

@Override
Expand All @@ -133,8 +146,7 @@ public void expireCardApiTicket() {
@Override
public void updateCardApiTicket(String cardApiTicket, int expiresInSeconds) {
this.cardApiTicket = cardApiTicket;
// 预留200秒的时间
this.cardApiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
this.cardApiTicketExpiresTime = expiresAheadInMillis(expiresInSeconds);
}

@Override
Expand Down
Loading