@@ -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"); | |||
} | |||
} | |||
} |
@@ -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; | |||
@@ -68,7 +82,7 @@ public class WxMaDefaultConfigImpl implements WxMaConfig { | |||
@Override | |||
public boolean isAccessTokenExpired() { | |||
return System.currentTimeMillis() > this.expiresTime; | |||
return isExpired(this.expiresTime); | |||
} | |||
@Override | |||
@@ -78,8 +92,8 @@ public class WxMaDefaultConfigImpl implements WxMaConfig { | |||
@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 | |||
@@ -94,7 +108,7 @@ public class WxMaDefaultConfigImpl implements WxMaConfig { | |||
@Override | |||
public boolean isJsapiTicketExpired() { | |||
return System.currentTimeMillis() > this.jsapiTicketExpiresTime; | |||
return isExpired(this.jsapiTicketExpiresTime); | |||
} | |||
@Override | |||
@@ -105,8 +119,7 @@ public class WxMaDefaultConfigImpl implements WxMaConfig { | |||
@Override | |||
public void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) { | |||
this.jsapiTicket = jsapiTicket; | |||
// 预留200秒的时间 | |||
this.jsapiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L; | |||
this.jsapiTicketExpiresTime = expiresAheadInMillis(expiresInSeconds); | |||
} | |||
@@ -122,7 +135,7 @@ public class WxMaDefaultConfigImpl implements WxMaConfig { | |||
@Override | |||
public boolean isCardApiTicketExpired() { | |||
return System.currentTimeMillis() > this.cardApiTicketExpiresTime; | |||
return isExpired(this.cardApiTicketExpiresTime); | |||
} | |||
@Override | |||
@@ -133,8 +146,7 @@ public class WxMaDefaultConfigImpl implements WxMaConfig { | |||
@Override | |||
public void updateCardApiTicket(String cardApiTicket, int expiresInSeconds) { | |||
this.cardApiTicket = cardApiTicket; | |||
// 预留200秒的时间 | |||
this.cardApiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L; | |||
this.cardApiTicketExpiresTime = expiresAheadInMillis(expiresInSeconds); | |||
} | |||
@Override | |||
@@ -1,377 +1,40 @@ | |||
package cn.binarywang.wx.miniapp.config.impl; | |||
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; | |||
import cn.binarywang.wx.miniapp.config.WxMaConfig; | |||
import com.github.jedis.lock.JedisLock; | |||
import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | |||
import me.chanjar.weixin.common.bean.WxAccessToken; | |||
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | |||
import redis.clients.jedis.Jedis; | |||
import redis.clients.jedis.JedisPool; | |||
/** | |||
* 基于Redis的微信配置provider. | |||
* 基于Redis的微信配置provider. 使用连接池 JedisPool 进行 Redis 操作。 | |||
* | |||
* <pre> | |||
* 需要引入依赖<a href="https://github.com/abelaska/jedis-lock">jedis-lock</a>,才能使用该类。 | |||
* </pre> | |||
* | |||
* @author <a href="https://github.com/winter4666">winter</a> | |||
*/ | |||
public class WxMaRedisConfigImpl implements WxMaConfig { | |||
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"; | |||
public class WxMaRedisConfigImpl extends AbstractWxMaRedisConfig { | |||
private JedisPool jedisPool; | |||
/** | |||
* 微信小程序唯一id,用于拼接存储到redis时的key,防止key重复. | |||
*/ | |||
private String maId; | |||
private volatile String msgDataFormat; | |||
protected volatile String appid; | |||
private volatile String secret; | |||
protected volatile String token; | |||
private volatile String aesKey; | |||
private volatile String httpProxyHost; | |||
private volatile int httpProxyPort; | |||
private volatile String httpProxyUsername; | |||
private volatile String httpProxyPassword; | |||
private Lock accessTokenLock; | |||
private Lock jsapiTicketLock; | |||
private Lock cardApiTicketLock; | |||
/** | |||
* 临时文件目录. | |||
* JedisPool 在此配置类是必须项,使用 WxMaRedisConfigImpl(JedisPool) 构造方法来构造实例 | |||
*/ | |||
protected volatile File tmpDirFile; | |||
private volatile ApacheHttpClientBuilder apacheHttpClientBuilder; | |||
private String getRedisKey(String key) { | |||
StringBuilder redisKey = new StringBuilder("maConfig:"); | |||
if (maId == null) { | |||
return redisKey.append(key).toString(); | |||
} else { | |||
return redisKey.append(maId).append(":").append(key).toString(); | |||
} | |||
@Deprecated | |||
public WxMaRedisConfigImpl() { | |||
} | |||
private String getValueFromRedis(String key) { | |||
try (Jedis jedis = jedisPool.getResource()) { | |||
return jedis.hget(getRedisKey(key), HASH_VALUE_FIELD); | |||
} | |||
} | |||
private void setValueToRedis(String key, long expiresTime, String value) { | |||
try (Jedis jedis = jedisPool.getResource()) { | |||
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 = jedisPool.getResource()) { | |||
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 = jedisPool.getResource()) { | |||
jedis.hset(getRedisKey(key), HASH_EXPIRE_FIELD, String.valueOf(expiresTime)); | |||
} | |||
public WxMaRedisConfigImpl(JedisPool jedisPool) { | |||
this.jedisPool = jedisPool; | |||
} | |||
/** | |||
* 使用 WxMaRedisConfigImpl(JedisPool) 构造方法来设置 JedisPool | |||
*/ | |||
@Deprecated | |||
public void setJedisPool(JedisPool jedisPool) { | |||
this.jedisPool = jedisPool; | |||
} | |||
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 System.currentTimeMillis() > getExpireFromRedis(ACCESS_TOKEN); | |||
} | |||
@Override | |||
public synchronized void updateAccessToken(WxAccessToken accessToken) { | |||
updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); | |||
} | |||
@Override | |||
public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) { | |||
setValueToRedis(ACCESS_TOKEN, System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L, 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 System.currentTimeMillis() > getExpireFromRedis(JSAPI_TICKET); | |||
} | |||
@Override | |||
public void expireJsapiTicket() { | |||
setExpire(JSAPI_TICKET, 0); | |||
} | |||
@Override | |||
public void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) { | |||
// 预留200秒的时间 | |||
setValueToRedis(JSAPI_TICKET, System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L, 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 System.currentTimeMillis() > 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, System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L, cardApiTicket); | |||
} | |||
@Override | |||
public void expireAccessToken() { | |||
setExpire(ACCESS_TOKEN, 0); | |||
} | |||
@Override | |||
public String getSecret() { | |||
return this.secret; | |||
} | |||
public void setSecret(String secret) { | |||
this.secret = secret; | |||
} | |||
@Override | |||
public String getToken() { | |||
return this.token; | |||
} | |||
public void setToken(String token) { | |||
this.token = token; | |||
} | |||
@Override | |||
public long getExpiresTime() { | |||
return getExpireFromRedis(ACCESS_TOKEN); | |||
} | |||
@Override | |||
public String getAesKey() { | |||
return this.aesKey; | |||
} | |||
public void setAesKey(String aesKey) { | |||
this.aesKey = aesKey; | |||
} | |||
@Override | |||
public String getMsgDataFormat() { | |||
return this.msgDataFormat; | |||
} | |||
public void setMsgDataFormat(String msgDataFormat) { | |||
this.msgDataFormat = msgDataFormat; | |||
} | |||
@Override | |||
public String getHttpProxyHost() { | |||
return this.httpProxyHost; | |||
} | |||
public void setHttpProxyHost(String httpProxyHost) { | |||
this.httpProxyHost = httpProxyHost; | |||
} | |||
@Override | |||
public int getHttpProxyPort() { | |||
return this.httpProxyPort; | |||
} | |||
public void setHttpProxyPort(int httpProxyPort) { | |||
this.httpProxyPort = httpProxyPort; | |||
} | |||
@Override | |||
public String getHttpProxyUsername() { | |||
return this.httpProxyUsername; | |||
} | |||
public void setHttpProxyUsername(String httpProxyUsername) { | |||
this.httpProxyUsername = httpProxyUsername; | |||
} | |||
@Override | |||
public String getHttpProxyPassword() { | |||
return this.httpProxyPassword; | |||
} | |||
public void setHttpProxyPassword(String httpProxyPassword) { | |||
this.httpProxyPassword = httpProxyPassword; | |||
} | |||
@Override | |||
public String toString() { | |||
return WxMaGsonBuilder.create().toJson(this); | |||
} | |||
@Override | |||
public ApacheHttpClientBuilder getApacheHttpClientBuilder() { | |||
return this.apacheHttpClientBuilder; | |||
} | |||
public void setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) { | |||
this.apacheHttpClientBuilder = apacheHttpClientBuilder; | |||
} | |||
@Override | |||
public boolean autoRefreshToken() { | |||
return true; | |||
} | |||
@Override | |||
public String getAppid() { | |||
return appid; | |||
} | |||
public void setAppid(String appid) { | |||
this.appid = appid; | |||
} | |||
/** | |||
* 基于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 = jedisPool.getResource()) { | |||
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 = jedisPool.getResource()) { | |||
if (!lock.acquire(jedis)) { | |||
throw new RuntimeException("acquire timeouted"); | |||
} | |||
} | |||
} | |||
@Override | |||
public boolean tryLock() { | |||
try (Jedis jedis = jedisPool.getResource()) { | |||
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 = jedisPool.getResource()) { | |||
return lock.acquire(jedis); | |||
} | |||
} | |||
@Override | |||
public void unlock() { | |||
try (Jedis jedis = jedisPool.getResource()) { | |||
lock.release(jedis); | |||
} | |||
} | |||
@Override | |||
public Condition newCondition() { | |||
throw new RuntimeException("unsupported method"); | |||
} | |||
protected Jedis getJedis() { | |||
return jedisPool.getResource(); | |||
} | |||
} |
@@ -0,0 +1,24 @@ | |||
package cn.binarywang.wx.miniapp.config.impl; | |||
import redis.clients.jedis.Jedis; | |||
/** | |||
* 基于Redis的微信配置provider. 使用自己管理的 Jedis 实例进行 Redis 操作。 | |||
* | |||
* <pre> | |||
* 需要引入依赖<a href="https://github.com/abelaska/jedis-lock">jedis-lock</a>,才能使用该类。 | |||
* </pre> | |||
*/ | |||
public class WxMaRedisConnectionConfigImpl extends AbstractWxMaRedisConfig { | |||
public WxMaRedisConnectionConfigImpl(Jedis jedis) { | |||
this.jedis = jedis; | |||
} | |||
private Jedis jedis; | |||
@Override | |||
protected Jedis getJedis() { | |||
return jedis; | |||
} | |||
} |