主頁 > 軟體設計 > 動態代理模式_應用(Redis工具類)

動態代理模式_應用(Redis工具類)

2020-09-14 13:24:57 軟體設計

本次使用動態代理的初衷是學習Redis,使用Java操作Redis時用到Jedis的JedisPool,而后對Jedis的方法進一步封裝完善成為一個工具類,
因為直接使用Jedis物件時,為了保證性能,總會需要手動的獲取到連接池中的連接,使用完成后還需要手動的釋放連接,都是完全重復的操作,
所以想要使用一些方法來抽取出這些重復操作,初時想到的是使用模板方法或是動態代理,但考慮到到模板方法會使用到大量的類,似乎與主旨不符,遂使用動態代理進行加強,

實作動態代理可使用JDK對應的方法,或是CGlib,由于工具類本身不會去定義介面,所以選擇CGlib,本身是在SpringBoot專案中進行,所以沒有額外匯入CGlib的包(spring的面向切面就使用到了CGlib與JDK自帶的動態 代理),

具體的思路就是使用動態代理來增強工具類物件,使得工具類在呼叫方法前后對應的進行獲取連接及釋放連接操作,在獲得到增強工具類后只需要進行相關操作即可,

使用了Maven來管理專案,代碼所需的依賴如下

1 <!-- Jedis -->
2 <dependency>
3     <groupId>com.redislabs</groupId>
4     <artifactId>jredisearch-jedis</artifactId>
5     <version>3.0.0-20180508</version>
6 </dependency>

此外還需要自己電腦安裝Redis,或有對應的服務器

代碼如下

 

Redis連接池代碼

 1 package com;
 2 
 3 import org.apache.logging.log4j.Logger;
 4 
 5 import redis.clients.jedis.Jedis;
 6 import redis.clients.jedis.JedisPool;
 7 import redis.clients.jedis.JedisPoolConfig;
 8 /**
 9  * Jedis連接池
10  * 
11  * @author zaizouGGG
12  *
13  */
14 public class RedisPool {
15     
16     private Logger logger = LogUtil.get(JedisUtil.class);
17     private static SysConfigUtil sysConfigUtil = SysConfigUtil.getSysConfigUtil("redis.properties");
18     
19     //宣告成static的原因:保證jedis連接池在tomcat啟動時就加載出來
20     //jedis連接池
21     private static JedisPool pool;
22     //與redis連接池連接的最大連接數
23     private static Integer maxTotal = sysConfigUtil.getInt("redis.maxTotal");
24     //在jedis連接池中最大的idle狀態(空閑的)的jedis實體的個數
25     private static Integer maxIdle = sysConfigUtil.getInt("redis.maxIdle");
26     //在jedis連接池中最小的idle狀態(空閑的)的jedis實體的個數
27     private static Integer minIdle = sysConfigUtil.getInt("redis.minIdle");
28     //在borrow一個jedis實體的時候,是否要進行驗證操作,如果賦值為true,則得到的jedis實體肯定是可用的
29     private static Boolean testOnBorrow = sysConfigUtil.getBoolean("redis.testOnBorrow");
30     //在return一個jedis實體的時候,是否要進行驗證操作,如果賦值為true,則回傳jedis連接池的jedis實體肯定是可用的
31     private static Boolean testOnReturn = sysConfigUtil.getBoolean("redis.testOnReturn");
32     private static String redisIp = sysConfigUtil.getString("redis.host");
33     private static Integer redisPort = sysConfigUtil.getInt("redis.port");
34     private static String password = sysConfigUtil.getString("redis.password");
35 
36     //初始化連接池,只會呼叫一次
37     private static void initPool() {
38         JedisPoolConfig config = new JedisPoolConfig();
39 
40         config.setMaxTotal(maxTotal);
41         config.setMaxIdle(maxIdle);
42         config.setMinIdle(minIdle);
43 
44         config.setTestOnBorrow(testOnBorrow);
45         config.setTestOnReturn(testOnReturn);
46 
47         //連接池耗盡的時候,是否阻塞,false會拋出例外,true阻塞直到超時,會拋出超時例外,默認為true
48         config.setBlockWhenExhausted(true);
49 
50         //這里超時時間是2s
51         if (password != null && !"".equals(password)) {
52             // redis 設定了密碼
53             pool = new JedisPool(config, redisIp, redisPort, 1000*2, password);
54         } else {
55             // redis 未設定密碼
56             pool = new JedisPool(config, redisIp, redisPort, 1000*2);
57         };
58         
59 
60     }
61 
62     static {
63         initPool();
64     }
65 
66     //從連接池中拿取一個實體
67     public static Jedis getJedis() {        
68         return pool.getResource();
69     }
70 
71     //返還Jedis
72     public static void returnJedis(Jedis jedis) {
73         jedis.close();
74     }
75 
76     //被使用的連接數
77     public static int getNumActive() {
78         return pool.getNumActive();
79     }
80     
81     //被阻塞的連接數?
82     public static int getNumWaiters() {
83         return pool.getNumWaiters();
84     }
85     
86     //空閑的連接數
87     public static int getNumIdle() {
88         return pool.getNumIdle();
89     }
90 }

讀取.properties組態檔的工具類

用于讀取配置在.properties中的引數

 1 package com;
 2 
 3 import java.io.BufferedInputStream;
 4 import java.io.FileInputStream;
 5 import java.io.IOException;
 6 import java.io.InputStream;
 7 import java.util.Properties;
 8 
 9 import org.apache.logging.log4j.Logger;
10 
11 /**
12  * 獲取自定義組態檔引數的共用方法
13  * 
14  * @author zaizouGGG
15 * 16 */ 17 public class SysConfigUtil { 18 19 private static Logger logger = LogUtil.get(SysConfigUtil.class); 20 private Properties properties = null; 21 22 public SysConfigUtil() { 23 24 } 25 26 public SysConfigUtil(Properties p) { 27 properties = p; 28 } 29 30 31 public static SysConfigUtil getSysConfigUtil(String url) { 32 try(InputStream in = new BufferedInputStream(new FileInputStream(url));) { 33 Properties p = new Properties(); 34 p.load(in); 35 //return p.getProperty("jdbc.type"); 36 return new SysConfigUtil(p); 37 } catch (IOException e) { 38 // TODO Auto-generated catch block 39 logger.error("Jedis工具類初始化失敗,讀取組態檔 "+url+" 出錯"); 40 e.printStackTrace(); 41 return null; 42 } 43 44 } 45 46 public String getString(String key) { 47 return properties.getProperty(key); 48 } 49 50 public int getInt(String key) { 51 int result = Integer.parseInt(properties.getProperty(key)); 52 return result; 53 } 54 55 public boolean getBoolean(String key) { 56 boolean result = Boolean.parseBoolean(properties.getProperty(key)); 57 return result; 58 } 59 60 public long getLong(String key) { 61 long result = Long.parseLong(properties.getProperty(key)); 62 return result; 63 } 64 }

Redis組態檔

此處的配置是我從網上找的,普通的使用沒有問題,要應用請慎重

redis.host=localhost
redis.port=6379
redis.password=root
#在指定時刻通過pool能夠獲取到的最大的連接的jedis個數
redis.maxTotal=8
#最大能夠保持idle的數量,控制一個pool最多有多少個狀態為idle的jedis實體
redis.maxIdle=8
#最小能夠保持idle的數量,控制一個pool最多有多少個狀態為idle的jedis實體
redis.minIdle=2
#在borrow一個jedis實體的時候,是否要進行驗證操作,如果賦值為true,則得到的jedis實體肯定是可用的
redis.testOnBorrow=true
#在return一個jedis實體的時候,是否要進行驗證操作,如果賦值為true,則回傳jedis連接池的jedis實體肯定是可用的
redis.testOnReturn=false
#當連接池內的連接耗盡時,getBlockWhenExhausted為true時,連接會阻塞,超過了阻塞的時間(設定的maxWaitMillis,單位毫秒)時會報錯
redis.maxWaitMillis=3000
#在borrow一個jedis實體時,是否提前進行validate操作;如果為true,則得到的jedis實體均是可用的;默認是false
redis.testOnBorrow=false

Jedis的工具類

 

  1 package com;
  2 
  3 import java.io.IOException;
  4 import java.util.List;
  5 import java.util.Map;
  6 import java.util.Set;
  7 
  8 import org.apache.logging.log4j.Logger;
  9 
 10 import redis.clients.jedis.Jedis;
 11 import redis.clients.jedis.JedisPool;
 12 import redis.clients.jedis.JedisPoolConfig;
 13 import redis.clients.jedis.ListPosition;
 14 
 15 /**
 16  * Jedis 通用工具類
 17  * @author zaizouGGG
 18  *
 19  */
 20 public class JedisUtil {
 21     
 22     private Logger logger = LogUtil.get(JedisUtil.class);
 23     private Jedis jedis = null;
 24     
 25     public Jedis getJedis() {
 26         return jedis;
 27     }
 28 
 29     public void setJedis(Jedis jedis) {
 30         this.jedis = jedis;
 31     }
 32 
 33     /**
 34      * 獲取指定key的值,如果key不存在回傳null,如果該Key存盤的不是字串,會拋出一個錯誤
 35      *
 36      * @param key
 37      * @return
 38      */
 39     public String get(String key) {
 40         String value =https://www.cnblogs.com/zaizouggg/p/ jedis.get(key);
 41         return value;
 42     }
 43 
 44     /**
 45      * 設定key的值為value
 46      *
 47      * @param key
 48      * @param value
 49      * @return
 50      */
 51     public String set(String key, String value) {
 52         String result = jedis.set(key, value);
 53         return result;
 54     }
 55     
 56     /**
 57      * 洗掉指定的key,也可以傳入一個包含key的陣列
 58      *
 59      * @param keys
 60      * @return
 61      */
 62     public Long del(String... keys) {
 63         
 64         return jedis.del(keys);
 65     }
 66 
 67     /**
 68      * 通過key向指定的value值追加值
 69      *
 70      * @param key
 71      * @param str
 72      * @return
 73      */
 74     public Long append(String key, String str) {
 75         
 76         return jedis.append(key, str);
 77     }
 78 
 79     /**
 80      * 判斷key是否存在
 81      *
 82      * @param key
 83      * @return
 84      */
 85     public Boolean exists(String key) {
 86         
 87         return jedis.exists(key);
 88     }
 89 
 90     /**
 91      * 設定key value,如果key已經存在則回傳0
 92      *
 93      * @param key
 94      * @param value
 95      * @return
 96      */
 97     public Long setnx(String key, String value) {
 98         
 99         return jedis.setnx(key, value);
100     }
101 
102     /**
103      * 設定key value并指定這個鍵值的有效期
104      *
105      * @param key
106      * @param seconds
107      * @param value
108      * @return
109      */
110     public String setex(String key, String value, int seconds) {
111         String result = jedis.setex(key, seconds, value);
112         return result;
113     }
114 
115     /**
116      * 通過key 和offset 從指定的位置開始將原先value替換
117      *
118      * @param key
119      * @param offset
120      * @param str
121      * @return
122      */
123     public Long setrange(String key, int offset, String str) {
124         
125         return jedis.setrange(key, offset, str);
126     }
127 
128     /**
129      * 通過批量的key獲取批量的value
130      *
131      * @param keys
132      * @return
133      */
134     public List<String> mget(String... keys) {
135         
136         return jedis.mget(keys);
137     }
138 
139     /**
140      * 批量的設定key:value,也可以一個
141      *
142      * @param keysValues
143      * @return
144      */
145     public String mset(String... keysValues) {
146         
147         return jedis.mset(keysValues);
148     }
149 
150     /**
151      * 批量的設定key:value,可以一個,如果key已經存在則會失敗,操作會回滾
152      *
153      * @param keysValues
154      * @return
155      */
156     public Long msetnx(String... keysValues) {
157         
158         return jedis.msetnx(keysValues);
159     }
160 
161     /**
162      * 設定key的值,并回傳一個舊值
163      *
164      * @param key
165      * @param value
166      * @return
167      */
168     public String getSet(String key, String value) {
169         
170         return jedis.getSet(key, value);
171     }
172 
173     /**
174      * 通過下標 和key 獲取指定下標位置的 value
175      *
176      * @param key
177      * @param startOffset
178      * @param endOffset
179      * @return
180      */
181     public String getrange(String key, int startOffset, int endOffset) {
182         
183         return jedis.getrange(key, startOffset, endOffset);
184     }
185 
186     /**
187      * 通過key 對value進行加值+1操作,當value不是int型別時會回傳錯誤,當key不存在是則value為1
188      *
189      * @param key
190      * @return
191      */
192     public Long incr(String key) {
193         
194         return jedis.incr(key);
195     }
196 
197     /**
198      * 通過key給指定的value加值,如果key不存在,則這是value為該值
199      *
200      * @param key
201      * @param integer
202      * @return
203      */
204     public Long incrBy(String key, long integer) {
205         
206         return jedis.incrBy(key, integer);
207     }
208 
209     /**
210      * 對key的值做減減操作,如果key不存在,則設定key為-1
211      *
212      * @param key
213      * @return
214      */
215     public Long decr(String key) {
216         
217         return jedis.decr(key);
218     }
219 
220     /**
221      * 減去指定的值
222      *
223      * @param key
224      * @param integer
225      * @return
226      */
227     public Long decrBy(String key, long integer) {
228         
229         return jedis.decrBy(key, integer);
230     }
231 
232     /**
233      * 通過key獲取value值的長度
234      *
235      * @param key
236      * @return
237      */
238     public Long strLen(String key) {
239         
240         return jedis.strlen(key);
241     }
242 
243     /**
244      * 通過key給field設定指定的值,如果key不存在則先創建,如果field已經存在,回傳0
245      *
246      * @param key
247      * @param field
248      * @param value
249      * @return
250      */
251     public Long hsetnx(String key, String field, String value) {
252         
253         return jedis.hsetnx(key, field, value);
254     }
255 
256     /**
257      * 通過key給field設定指定的值,如果key不存在,則先創建
258      *
259      * @param key
260      * @param field
261      * @param value
262      * @return
263      */
264     public Long hset(String key, String field, String value) {
265         
266         return jedis.hset(key, field, value);
267     }
268 
269     /**
270      * 通過key同時設定 hash的多個field
271      *
272      * @param key
273      * @param hash
274      * @return
275      */
276     public String hmset(String key, Map<String, String> hash) {
277         
278         return jedis.hmset(key, hash);
279     }
280 
281     /**
282      * 通過key 和 field 獲取指定的 value
283      *
284      * @param key
285      * @param failed
286      * @return
287      */
288     public String hget(String key, String failed) {
289         
290         return jedis.hget(key, failed);
291     }
292 
293     /**
294      * 設定key的超時時間為seconds
295      *
296      * @param key
297      * @param seconds
298      * @return
299      */
300     public Long expire(String key, int seconds) {
301         
302         return jedis.expire(key, seconds);
303     }
304 
305     /**
306      * 通過key 和 fields 獲取指定的value 如果沒有對應的value則回傳null
307      *
308      * @param key
309      * @param fields 可以是 一個String 也可以是 String陣列
310      * @return
311      */
312     public List<String> hmget(String key, String... fields) {
313         
314         return jedis.hmget(key, fields);
315     }
316 
317     /**
318      * 通過key給指定的field的value加上給定的值
319      *
320      * @param key
321      * @param field
322      * @param value
323      * @return
324      */
325     public Long hincrby(String key, String field, Long value) {
326         
327         return jedis.hincrBy(key, field, value);
328     }
329 
330     /**
331      * 通過key和field判斷是否有指定的value存在
332      *
333      * @param key
334      * @param field
335      * @return
336      */
337     public Boolean hexists(String key, String field) {
338         
339         return jedis.hexists(key, field);
340     }
341 
342     /**
343      * 通過key回傳field的數量
344      *
345      * @param key
346      * @return
347      */
348     public Long hlen(String key) {
349         
350         return jedis.hlen(key);
351     }
352 
353     /**
354      * 通過key 洗掉指定的 field
355      *
356      * @param key
357      * @param fields 可以是 一個 field 也可以是 一個陣列
358      * @return
359      */
360     public Long hdel(String key, String... fields) {
361         
362         return jedis.hdel(key, fields);
363     }
364 
365     /**
366      * 通過key回傳所有的field
367      *
368      * @param key
369      * @return
370      */
371     public Set<String> hkeys(String key) {
372         
373         return jedis.hkeys(key);
374     }
375 
376     /**
377      * 通過key回傳所有和key有關的value
378      *
379      * @param key
380      * @return
381      */
382     public List<String> hvals(String key) {
383         
384         return jedis.hvals(key);
385     }
386 
387     /**
388      * 通過key獲取所有的field和value
389      *
390      * @param key
391      * @return
392      */
393     public Map<String, String> hgetall(String key) {
394         
395         return jedis.hgetAll(key);
396     }
397 
398     /**
399      * 通過key向list頭部添加字串
400      *
401      * @param key
402      * @param strs 可以是一個string 也可以是string陣列
403      * @return 回傳list的value個數
404      */
405     public Long lpush(String key, String... strs) {
406         
407         return jedis.lpush(key, strs);
408     }
409 
410     /**
411      * 通過key向list尾部添加字串
412      *
413      * @param key
414      * @param strs 可以是一個string 也可以是string陣列
415      * @return 回傳list的value個數
416      */
417     public Long rpush(String key, String... strs) {
418         
419         return jedis.rpush(key, strs);
420     }
421 
422     /**
423      * 通過key在list指定的位置之前或者之后 添加字串元素
424      *
425      * @param key
426      * @param where LIST_POSITION列舉型別
427      * @param pivot list里面的value
428      * @param value 添加的value
429      * @return
430      */
431     public Long linsert(String key, ListPosition where,
432                         String pivot, String value) {
433         
434         return jedis.linsert(key, where, pivot, value);
435     }
436 
437     /**
438      * 通過key設定list指定下標位置的value
439      * 如果下標超過list里面value的個數則報錯
440      *
441      * @param key
442      * @param index 從0開始
443      * @param value
444      * @return 成功回傳OK
445      */
446     public String lset(String key, Long index, String value) {
447         
448         return jedis.lset(key, index, value);
449     }
450 
451     /**
452      * 通過key從對應的list中洗掉指定的count個 和 value相同的元素
453      *
454      * @param key
455      * @param count 當count為0時洗掉全部
456      * @param value
457      * @return 回傳被洗掉的個數
458      */
459     public Long lrem(String key, long count, String value) {
460         
461         return jedis.lrem(key, count, value);
462     }
463 
464     /**
465      * 通過key保留list中從strat下標開始到end下標結束的value值
466      *
467      * @param key
468      * @param start
469      * @param end
470      * @return 成功回傳OK
471      */
472     public String ltrim(String key, long start, long end) {
473         
474         return jedis.ltrim(key, start, end);
475     }
476 
477     /**
478      * 通過key從list的頭部洗掉一個value,并回傳該value
479      *
480      * @param key
481      * @return
482      */
483     public synchronized String lpop(String key) {
484 
485         
486         return jedis.lpop(key);
487     }
488 
489     /**
490      * 通過key從list尾部洗掉一個value,并回傳該元素
491      *
492      * @param key
493      * @return
494      */
495     synchronized public String rpop(String key) {
496         
497         return jedis.rpop(key);
498     }
499 
500     /**
501      * 通過key從一個list的尾部洗掉一個value并添加到另一個list的頭部,并回傳該value
502      * 如果第一個list為慷訓者不存在則回傳null
503      *
504      * @param srckey
505      * @param dstkey
506      * @return
507      */
508     public String rpoplpush(String srckey, String dstkey) {
509         
510         return jedis.rpoplpush(srckey, dstkey);
511     }
512 
513     /**
514      * 通過key獲取list中指定下標位置的value
515      *
516      * @param key
517      * @param index
518      * @return 如果沒有回傳null
519      */
520     public String lindex(String key, long index) {
521         
522         return jedis.lindex(key, index);
523     }
524 
525     /**
526      * 通過key回傳list的長度
527      *
528      * @param key
529      * @return
530      */
531     public Long llen(String key) {
532         
533         return jedis.llen(key);
534     }
535 
536     /**
537      * 通過key獲取list指定下標位置的value
538      * 如果start 為 0 end 為 -1 則回傳全部的list中的value
539      *
540      * @param key
541      * @param start
542      * @param end
543      * @return
544      */
545     public List<String> lrange(String key, long start, long end) {
546         
547         return jedis.lrange(key, start, end);
548     }
549 
550     /**
551      * 通過key向指定的set中添加value
552      *
553      * @param key
554      * @param members 可以是一個String 也可以是一個String陣列
555      * @return 添加成功的個數
556      */
557     public Long sadd(String key, String... members) {
558         
559         return jedis.sadd(key, members);
560     }
561 
562     /**
563      * 通過key洗掉set中對應的value值
564      *
565      * @param key
566      * @param members 可以是一個String 也可以是一個String陣列
567      * @return 洗掉的個數
568      */
569     public Long srem(String key, String... members) {
570         
571         return jedis.srem(key, members);
572     }
573 
574     /**
575      * 通過key隨機洗掉一個set中的value并回傳該值
576      *
577      * @param key
578      * @return
579      */
580     public String spop(String key) {
581         
582         return jedis.spop(key);
583     }
584 
585     /**
586      * 通過key獲取set中的差集
587      * 以第一個set為標準
588      *
589      * @param keys 可以 是一個string 則回傳set中所有的value 也可以是string陣列
590      * @return
591      */
592     public Set<String> sdiff(String... keys) {
593         
594         return jedis.sdiff(keys);
595     }
596 
597     /**
598      * 通過key獲取set中的差集并存入到另一個key中
599      * 以第一個set為標準
600      *
601      * @param dstkey 差集存入的key
602      * @param keys   可以 是一個string 則回傳set中所有的value 也可以是string陣列
603      * @return
604      */
605     public Long sdiffstore(String dstkey, String... keys) {
606         
607         return jedis.sdiffstore(dstkey, keys);
608     }
609 
610     /**
611      * 通過key獲取指定set中的交集
612      *
613      * @param keys 可以 是一個string 也可以是一個string陣列
614      * @return
615      */
616     public Set<String> sinter(String... keys) {
617         
618         return jedis.sinter(keys);
619     }
620 
621     /**
622      * 通過key獲取指定set中的交集 并將結果存入新的set中
623      *
624      * @param dstkey
625      * @param keys   可以 是一個string 也可以是一個string陣列
626      * @return
627      */
628     public Long sinterstore(String dstkey, String... keys) {
629         
630         return jedis.sinterstore(dstkey, keys);
631     }
632 
633     /**
634      * 通過key回傳所有set的并集
635      *
636      * @param keys 可以 是一個string 也可以是一個string陣列
637      * @return
638      */
639     public Set<String> sunion(String... keys) {
640         
641         return jedis.sunion(keys);
642     }
643 
644     /**
645      * 通過key回傳所有set的并集,并存入到新的set中
646      *
647      * @param dstkey
648      * @param keys   可以 是一個string 也可以是一個string陣列
649      * @return
650      */
651     public Long sunionstore(String dstkey, String... keys) {
652         
653         return jedis.sunionstore(dstkey, keys);
654     }
655 
656     /**
657      * 通過key將set中的value移除并添加到第二個set中
658      *
659      * @param srckey 需要移除的
660      * @param dstkey 添加的
661      * @param member set中的value
662      * @return
663      */
664     public Long smove(String srckey, String dstkey, String member) {
665         
666         return jedis.smove(srckey, dstkey, member);
667     }
668 
669     /**
670      * 通過key獲取set中value的個數
671      *
672      * @param key
673      * @return
674      */
675     public Long scard(String key) {
676         
677         return jedis.scard(key);
678     }
679 
680     /**
681      * 通過key判斷value是否是set中的元素
682      *
683      * @param key
684      * @param member
685      * @return
686      */
687     public Boolean sismember(String key, String member) {
688         
689         return jedis.sismember(key, member);
690     }
691 
692     /**
693      * 通過key獲取set中隨機的value,不洗掉元素
694      *
695      * @param key
696      * @return
697      */
698     public String srandmember(String key) {
699         
700         return jedis.srandmember(key);
701     }
702 
703     /**
704      * 通過key獲取set中所有的value
705      *
706      * @param key
707      * @return
708      */
709     public Set<String> smembers(String key) {
710         
711         return jedis.smembers(key);
712     }
713 
714 
715     /**
716      * 通過key向zset中添加value,score,其中score就是用來排序的
717      * 如果該value已經存在則根據score更新元素
718      *
719      * @param key
720      * @param score
721      * @param member
722      * @return
723      */
724     public Long zadd(String key, double score, String member) {
725         
726         return jedis.zadd(key, score, member);
727     }
728 
729     /**
730      * 通過key洗掉在zset中指定的value
731      *
732      * @param key
733      * @param members 可以 是一個string 也可以是一個string陣列
734      * @return
735      */
736     public Long zrem(String key, String... members) {
737         
738         return jedis.zrem(key, members);
739     }
740 
741     /**
742      * 通過key增加該zset中value的score的值
743      *
744      * @param key
745      * @param score
746      * @param member
747      * @return
748      */
749     public Double zincrby(String key, double score, String member) {
750         
751         return jedis.zincrby(key, score, member);
752     }
753 
754     /**
755      * 通過key回傳zset中value的排名
756      * 下標從小到大排序
757      *
758      * @param key
759      * @param member
760      * @return
761      */
762     public Long zrank(String key, String member) {
763         
764         return jedis.zrank(key, member);
765     }
766 
767     /**
768      * 通過key回傳zset中value的排名
769      * 下標從大到小排序
770      *
771      * @param key
772      * @param member
773      * @return
774      */
775     public Long zrevrank(String key, String member) {
776         
777         return jedis.zrevrank(key, member);
778     }
779 
780     /**
781      * 通過key將獲取score從start到end中zset的value
782      * socre從大到小排序
783      * 當start為0 end為-1時回傳全部
784      *
785      * @param key
786      * @param start
787      * @param end
788      * @return
789      */
790     public Set<String> zrevrange(String key, long start, long end) {
791         
792         return jedis.zrevrange(key, start, end);
793     }
794 
795     /**
796      * 通過key回傳指定score內zset中的value
797      *
798      * @param key
799      * @param max
800      * @param min
801      * @return
802      */
803     public Set<String> zrangebyscore(String key, String max, String min) {
804         
805         return jedis.zrevrangeByScore(key, max, min);
806     }
807 
808     /**
809      * 通過key回傳指定score內zset中的value
810      *
811      * @param key
812      * @param max
813      * @param min
814      * @return
815      */
816     public Set<String> zrangeByScore(String key, double max, double min) {
817         
818         return jedis.zrevrangeByScore(key, max, min);
819     }
820 
821     /**
822      * 回傳指定區間內zset中value的數量
823      *
824      * @param key
825      * @param min
826      * @param max
827      * @return
828      */
829     public Long zcount(String key, String min, String max) {
830         
831         return jedis.zcount(key, min, max);
832     }
833 
834     /**
835      * 通過key回傳zset中的value個數
836      *
837      * @param key
838      * @return
839      */
840     public Long zcard(String key) {
841         
842         return jedis.zcard(key);
843     }
844 
845     /**
846      * 通過key獲取zset中value的score值
847      *
848      * @param key
849      * @param member
850      * @return
851      */
852     public Double zscore(String key, String member) {
853         
854         return jedis.zscore(key, member);
855     }
856 
857     /**
858      * 通過key洗掉給定區間內的元素
859      *
860      * @param key
861      * @param start
862      * @param end
863      * @return
864      */
865     public Long zremrangeByRank(String key, long start, long end) {
866         
867         return jedis.zremrangeByRank(key, start, end);
868     }
869 
870     /**
871      * 通過key洗掉指定score內的元素
872      *
873      * @param key
874      * @param start
875      * @param end
876      * @return
877      */
878     public Long zremrangeByScore(String key, double start, double end) {
879         
880         return jedis.zremrangeByScore(key, start, end);
881     }
882  
883     /**
884      * 回傳滿足pattern運算式的所有key
885      * keys(*)
886      * 回傳所有的key
887      *
888      * @param pattern
889      * @return
890      */
891     public Set<String> keys(String pattern) {
892         
893         return jedis.keys(pattern);
894     }
895 
896     /**
897      * 通過key判斷值得型別
898      *
899      * @param key
900      * @return
901      */
902     public String type(String key) {
903         
904         return jedis.type(key);
905     }
906 
907 
908     /**
909      * 回傳一個CGlib增強的工具類物件
910      * @return
911      */
912     public static JedisUtil getJedisUtil() {
913         RedisInterceptor redisInterceptor = new RedisInterceptor();
914         JedisUtil jedisUtil = (JedisUtil) redisInterceptor.getInstance(new JedisUtil());
915         return jedisUtil;
916     }
917 
918 }
View Code

 

 

 

 

Jedis工具類的動態代理類

 1 package com;
 2 
 3 import java.lang.reflect.Method;
 4 
 5 import org.apache.logging.log4j.Logger;
 6 import org.springframework.cglib.proxy.Enhancer;
 7 import org.springframework.cglib.proxy.MethodInterceptor;
 8 import org.springframework.cglib.proxy.MethodProxy;
 9 
10 /**
11  * Jedis工具類的動態代理
12  * 自動獲取連接及歸還連接
13  * @author zaizouGGG
14 * 15 */ 16 public class RedisInterceptor implements MethodInterceptor { 17 18 private Logger logger = LogUtil.get(RedisInterceptor.class); 19 private JedisUtil targetObject; 20 // 這里的目標型別為Object,則可以接受任意一種引數作為被代理類,實作了動態代理 21 public Object getInstance(JedisUtil target) { 22 // 設定需要創建子類的類 23 this.targetObject = target; 24 Enhancer enhancer = new Enhancer(); 25 enhancer.setSuperclass(target.getClass()); 26 enhancer.setCallback(this); 27 return enhancer.create(); 28 } 29 30 @Override 31 public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { 32 // TODO Auto-generated method stub 33 targetObject.setJedis(RedisPool.getJedis()); 34 logger.info("獲取連接后連接池狀態"+RedisPool.getNumActive() + "-" + RedisPool.getNumIdle() + "-" + RedisPool.getNumWaiters()); 35 Object result = proxy.invoke(targetObject, args); 36 RedisPool.returnJedis(targetObject.getJedis()); 37 logger.info("歸還連接后連接池狀態"+RedisPool.getNumActive() + "-" + RedisPool.getNumIdle() + "-" + RedisPool.getNumWaiters()); 38 return result; 39 } 40 41 }

 

操作代碼

public static void main(String[] args){
    //實體化一個增強的工具類
    JedisUtil jedisUtil = JedisUtil.getJedisUtil();
    //進行相關操作即可
    value =https://www.cnblogs.com/zaizouggg/p/ jedisUtil.get(key);
}

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/35327.html

標籤:設計模式

上一篇:單例模式

下一篇:代理模式

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more