因爲這段時間使用SpringBoot的緣由,不少東西都用了SpringBoot內部的Template來作,也沒關心底層怎麼操做的。最近忙裏偷閒回答了幾個問題,正巧看到一個關於Redis資源釋放問題的,引發了個人興趣,便去看了下官方文檔。
Redis推薦的Java客戶端是jedis,關於Jedis的配置那些我就不說了,直接上他的示例代碼java
You use it by:git
/// Jedis implements Closeable. Hence, the jedis instance will be auto-closed after the last statement. try (Jedis jedis = pool.getResource()) { /// ... do stuff here ... for example jedis.set("foo", "bar"); String foobar = jedis.get("foo"); jedis.zadd("sose", 0, "car"); jedis.zadd("sose", 0, "bike"); Set<String> sose = jedis.zrange("sose", 0, -1); } /// ... when closing your application: pool.destroy();If you can't use try-with-resource, you can still enjoy with Jedis.close().github
Jedis jedis = null; try { jedis = pool.getResource(); /// ... do stuff here ... for example jedis.set("foo", "bar"); String foobar = jedis.get("foo"); jedis.zadd("sose", 0, "car"); jedis.zadd("sose", 0, "bike"); Set<String> sose = jedis.zrange("sose", 0, -1); } finally { // You have to close jedis object. If you don't close then // it doesn't release back to pool and you can't get a new // resource from pool. if (jedis != null) { jedis.close(); } } /// ... when closing your application: pool.destroy();If Jedis was borrowed from pool, it will be returned to pool with
proper method since it already determines there was
JedisConnectionException occurred. If Jedis wasn't borrowed from pool,
it will be disconnected and closed.redis
也就是說要麼用Java7的try-with-resource關閉資源,要麼就try finally。
唉,又該有人吐槽Java又臭又長了,像老太婆的裹腳布同樣。
怎麼辦呢?
咱們能夠寫一個方法把全部的redis操做包裝起來,裏面加上資源釋放。
呃?工程量好像有點大,並且沒逼格。。。
想啊想啊想,能不能在執行Jedis方法的時候加上咱們的代碼呢?好比在以前獲取鏈接池中的實例,在以後釋放資源。
咦,好像aop能夠實現啊。
可是我就想用Java8的Lambda裝裝逼。app
首先,咱們看下這個Java內置的函數式接口中的apply方法,解釋爲「將給定的參數應用於該函數」。函數
能夠,正是咱們須要的。
開始愉快的編碼吧。測試
建立一個Maven工程,指定編譯版本和運行版本爲jdk1.8,加入jedis依賴。編碼
編寫Jedis配置類。spa
import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; public class RedisConf { private static JedisPool pool; private RedisConf(){} static { pool = new JedisPool(new JedisPoolConfig(), "192.168.100.15",6379,60000,"密碼手動打碼",13); } public static JedisPool getJedisPool() { return pool; } }
編寫執行器code
import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import java.util.function.Function; public class RedisActuator { private JedisPool jedisPool = RedisConf.getJedisPool(); public <R> R execute(Function<Jedis, R> fun) { try (Jedis jedis = jedisPool.getResource()){ return fun.apply(jedis); } catch (Exception e) { e.printStackTrace(); } return null; } }
編寫測試代碼(Jedis官方文檔中的示例代碼)
import com.fanxian.redis.RedisActuator; import java.util.Set; public class App { public static void main( String[] args ) { RedisActuator redisActuator = new RedisActuator(); redisActuator.execute(jedis -> jedis.set("foo", "bar")); String foobar = redisActuator.execute(jedis -> jedis.get("foo")); System.out.println(foobar); redisActuator.execute(jedis -> jedis.zadd("sose", 0, "car")); redisActuator.execute(jedis -> jedis.zadd("sose", 0, "bike")); Set<String> sose = redisActuator.execute(jedis -> jedis.zrange("sose", 0, -1)); System.out.println(sose); } }
好像代碼也沒簡化多少。
本文代碼:( 裝了逼趕忙逃。