Skip to content

Commit 232ea7e

Browse files
xJoeWoobinarywang
authored andcommitted
🎨 #1314 优化增强微信小程序Redis配置实现类功能
修改 Redis 配置实现类以实现选择数据库及密码认证功能
1 parent d4d830f commit 232ea7e

File tree

4 files changed

+338
-359
lines changed

4 files changed

+338
-359
lines changed
Lines changed: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,280 @@
1+
package cn.binarywang.wx.miniapp.config.impl;
2+
3+
import com.github.jedis.lock.JedisLock;
4+
import redis.clients.jedis.Jedis;
5+
6+
import java.io.File;
7+
import java.util.HashMap;
8+
import java.util.Map;
9+
import java.util.concurrent.TimeUnit;
10+
import java.util.concurrent.locks.Condition;
11+
import java.util.concurrent.locks.Lock;
12+
13+
/**
14+
* @author <a href="https://github.com/winter4666">winter</a>
15+
*/
16+
public abstract class AbstractWxMaRedisConfig extends WxMaDefaultConfigImpl {
17+
18+
public interface JedisConfig {
19+
Jedis config(Jedis jedis);
20+
}
21+
22+
private static final String ACCESS_TOKEN = "accessToken";
23+
private static final String JSAPI_TICKET = "jsapiTicket";
24+
private static final String CARD_API_TICKET = "cardApiTicket";
25+
26+
private static final String HASH_VALUE_FIELD = "value";
27+
private static final String HASH_EXPIRE_FIELD = "expire";
28+
29+
/**
30+
* Redis Key 的前缀,默认为 maConfig
31+
*/
32+
private String redisKeyPrefix = "maConfig";
33+
34+
/**
35+
* 微信小程序唯一id,用于拼接存储到redis时的key,防止key重复.
36+
*/
37+
private String maId;
38+
39+
private Lock accessTokenLock;
40+
private Lock jsapiTicketLock;
41+
private Lock cardApiTicketLock;
42+
43+
/**
44+
* 临时文件目录.
45+
*/
46+
protected volatile File tmpDirFile;
47+
48+
/**
49+
* 对从 JedisPool.getResource() 获取到的每个 Jedis 实例进行配置
50+
*/
51+
private JedisConfig jedisConfig;
52+
53+
protected abstract Jedis getJedis();
54+
55+
private Jedis getConfiguredJedis() {
56+
Jedis jedis = getJedis();
57+
if (jedisConfig != null) {
58+
return jedisConfig.config(jedis);
59+
} else {
60+
return jedis;
61+
}
62+
}
63+
64+
private String getRedisKey(String key) {
65+
StringBuilder redisKey = new StringBuilder(redisKeyPrefix).append(":");
66+
if (maId == null) {
67+
return redisKey.append(key).toString();
68+
} else {
69+
return redisKey.append(maId).append(":").append(key).toString();
70+
}
71+
}
72+
73+
private String getValueFromRedis(String key) {
74+
try (Jedis jedis = getConfiguredJedis()) {
75+
return jedis.hget(getRedisKey(key), HASH_VALUE_FIELD);
76+
}
77+
}
78+
79+
private void setValueToRedis(String key, long expiresTime, String value) {
80+
try (Jedis jedis = getConfiguredJedis()) {
81+
Map<String, String> hash = new HashMap<String, String>();
82+
hash.put(HASH_VALUE_FIELD, value);
83+
hash.put(HASH_EXPIRE_FIELD, String.valueOf(expiresTime));
84+
jedis.hmset(getRedisKey(key), hash);
85+
}
86+
}
87+
88+
private long getExpireFromRedis(String key) {
89+
try (Jedis jedis = getConfiguredJedis()) {
90+
String expire = jedis.hget(getRedisKey(key), HASH_EXPIRE_FIELD);
91+
return expire == null ? 0 : Long.parseLong(expire);
92+
}
93+
}
94+
95+
private void setExpire(String key, long expiresTime) {
96+
try (Jedis jedis = getConfiguredJedis()) {
97+
jedis.hset(getRedisKey(key), HASH_EXPIRE_FIELD, String.valueOf(expiresTime));
98+
}
99+
}
100+
101+
public void setRedisKeyPrefix(String redisKeyPrefix) {
102+
this.redisKeyPrefix = redisKeyPrefix;
103+
}
104+
105+
public void setJedisConfig(JedisConfig jedisConfig) {
106+
this.jedisConfig = jedisConfig;
107+
}
108+
109+
public void setMaId(String maId) {
110+
this.maId = maId;
111+
}
112+
113+
@Override
114+
public String getAccessToken() {
115+
return getValueFromRedis(ACCESS_TOKEN);
116+
}
117+
118+
@Override
119+
public Lock getAccessTokenLock() {
120+
if (accessTokenLock == null) {
121+
synchronized (this) {
122+
if (accessTokenLock == null) {
123+
accessTokenLock = new DistributedLock(getRedisKey("accessTokenLock"));
124+
}
125+
}
126+
}
127+
return accessTokenLock;
128+
}
129+
130+
@Override
131+
public boolean isAccessTokenExpired() {
132+
return isExpired(getExpireFromRedis(ACCESS_TOKEN));
133+
}
134+
135+
@Override
136+
public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) {
137+
setValueToRedis(ACCESS_TOKEN, expiresAheadInMillis(expiresInSeconds), accessToken);
138+
}
139+
140+
@Override
141+
public String getJsapiTicket() {
142+
return getValueFromRedis(JSAPI_TICKET);
143+
}
144+
145+
@Override
146+
public Lock getJsapiTicketLock() {
147+
if (jsapiTicketLock == null) {
148+
synchronized (this) {
149+
if (jsapiTicketLock == null) {
150+
jsapiTicketLock = new DistributedLock(getRedisKey("jsapiTicketLock"));
151+
}
152+
}
153+
}
154+
return jsapiTicketLock;
155+
}
156+
157+
@Override
158+
public boolean isJsapiTicketExpired() {
159+
return isExpired(getExpireFromRedis(JSAPI_TICKET));
160+
}
161+
162+
@Override
163+
public void expireJsapiTicket() {
164+
setExpire(JSAPI_TICKET, 0);
165+
}
166+
167+
@Override
168+
public void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) {
169+
setValueToRedis(JSAPI_TICKET, expiresAheadInMillis(expiresInSeconds), jsapiTicket);
170+
}
171+
172+
173+
@Override
174+
public String getCardApiTicket() {
175+
return getValueFromRedis(CARD_API_TICKET);
176+
}
177+
178+
@Override
179+
public Lock getCardApiTicketLock() {
180+
if (cardApiTicketLock == null) {
181+
synchronized (this) {
182+
if (cardApiTicketLock == null) {
183+
cardApiTicketLock = new DistributedLock(getRedisKey("cardApiTicketLock"));
184+
}
185+
}
186+
}
187+
return cardApiTicketLock;
188+
}
189+
190+
@Override
191+
public boolean isCardApiTicketExpired() {
192+
return isExpired(getExpireFromRedis(CARD_API_TICKET));
193+
}
194+
195+
@Override
196+
public void expireCardApiTicket() {
197+
setExpire(CARD_API_TICKET, 0);
198+
}
199+
200+
@Override
201+
public void updateCardApiTicket(String cardApiTicket, int expiresInSeconds) {
202+
setValueToRedis(CARD_API_TICKET, expiresAheadInMillis(expiresInSeconds), cardApiTicket);
203+
}
204+
205+
@Override
206+
public void expireAccessToken() {
207+
setExpiresTime(0);
208+
}
209+
210+
@Override
211+
public long getExpiresTime() {
212+
return getExpireFromRedis(ACCESS_TOKEN);
213+
}
214+
215+
@Override
216+
public void setExpiresTime(long expiresTime) {
217+
setExpire(ACCESS_TOKEN, expiresTime);
218+
}
219+
220+
/**
221+
* 基于redis的简单分布式锁.
222+
*/
223+
private class DistributedLock implements Lock {
224+
225+
private JedisLock lock;
226+
227+
private DistributedLock(String key) {
228+
this.lock = new JedisLock(getRedisKey(key));
229+
}
230+
231+
@Override
232+
public void lock() {
233+
try (Jedis jedis = getConfiguredJedis()) {
234+
if (!lock.acquire(jedis)) {
235+
throw new RuntimeException("acquire timeouted");
236+
}
237+
} catch (InterruptedException e) {
238+
throw new RuntimeException("lock failed", e);
239+
}
240+
}
241+
242+
@Override
243+
public void lockInterruptibly() throws InterruptedException {
244+
try (Jedis jedis = getConfiguredJedis()) {
245+
if (!lock.acquire(jedis)) {
246+
throw new RuntimeException("acquire timeouted");
247+
}
248+
}
249+
}
250+
251+
@Override
252+
public boolean tryLock() {
253+
try (Jedis jedis = getConfiguredJedis()) {
254+
return lock.acquire(jedis);
255+
} catch (InterruptedException e) {
256+
throw new RuntimeException("lock failed", e);
257+
}
258+
}
259+
260+
@Override
261+
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
262+
try (Jedis jedis = getConfiguredJedis()) {
263+
return lock.acquire(jedis);
264+
}
265+
}
266+
267+
@Override
268+
public void unlock() {
269+
try (Jedis jedis = getConfiguredJedis()) {
270+
lock.release(jedis);
271+
}
272+
}
273+
274+
@Override
275+
public Condition newCondition() {
276+
throw new RuntimeException("unsupported method");
277+
}
278+
279+
}
280+
}

weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/WxMaDefaultConfigImpl.java

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,20 @@ public class WxMaDefaultConfigImpl implements WxMaConfig {
4848

4949
private volatile ApacheHttpClientBuilder apacheHttpClientBuilder;
5050

51+
/**
52+
* 会过期的数据提前过期时间,默认预留200秒的时间
53+
*/
54+
protected long expiresAheadInMillis(int expiresInSeconds) {
55+
return System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
56+
}
57+
58+
/**
59+
* 判断 expiresTime 是否已经过期
60+
*/
61+
protected boolean isExpired(long expiresTime) {
62+
return System.currentTimeMillis() > expiresTime;
63+
}
64+
5165
@Override
5266
public String getAccessToken() {
5367
return this.accessToken;
@@ -68,7 +82,7 @@ public void setAccessTokenLock(Lock accessTokenLock) {
6882

6983
@Override
7084
public boolean isAccessTokenExpired() {
71-
return System.currentTimeMillis() > this.expiresTime;
85+
return isExpired(this.expiresTime);
7286
}
7387

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

7993
@Override
8094
public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) {
81-
this.accessToken = accessToken;
82-
this.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
95+
setAccessToken(accessToken);
96+
setExpiresTime(expiresAheadInMillis(expiresInSeconds));
8397
}
8498

8599
@Override
@@ -94,7 +108,7 @@ public Lock getJsapiTicketLock() {
94108

95109
@Override
96110
public boolean isJsapiTicketExpired() {
97-
return System.currentTimeMillis() > this.jsapiTicketExpiresTime;
111+
return isExpired(this.jsapiTicketExpiresTime);
98112
}
99113

100114
@Override
@@ -105,8 +119,7 @@ public void expireJsapiTicket() {
105119
@Override
106120
public void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) {
107121
this.jsapiTicket = jsapiTicket;
108-
// 预留200秒的时间
109-
this.jsapiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
122+
this.jsapiTicketExpiresTime = expiresAheadInMillis(expiresInSeconds);
110123
}
111124

112125

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

123136
@Override
124137
public boolean isCardApiTicketExpired() {
125-
return System.currentTimeMillis() > this.cardApiTicketExpiresTime;
138+
return isExpired(this.cardApiTicketExpiresTime);
126139
}
127140

128141
@Override
@@ -133,8 +146,7 @@ public void expireCardApiTicket() {
133146
@Override
134147
public void updateCardApiTicket(String cardApiTicket, int expiresInSeconds) {
135148
this.cardApiTicket = cardApiTicket;
136-
// 预留200秒的时间
137-
this.cardApiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
149+
this.cardApiTicketExpiresTime = expiresAheadInMillis(expiresInSeconds);
138150
}
139151

140152
@Override

0 commit comments

Comments
 (0)