前言
由于这段时间使用SpringBoot的原因,很多东西都用了SpringBoot内部的Template来做,也没关心底层怎么操作的。最近忙里偷闲回答了几个问题,正巧看到一个关于Redis资源释放问题的,引起了我的兴趣,便去看了下官方文档。
Redis推荐的Java客户端是jedis,关于Jedis的配置那些我就不说了,直接上他的示例代码
You use it by:
/// 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().
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.
也就是说要么用Java7的try-with-resource关闭资源,要么就try finally。
唉,又该有人吐槽Java又臭又长了,像老太婆的裹脚布一样。
怎么办呢?
我们可以写一个方法把所有的redis操作包装起来,里面加上资源释放。
呃?工程量好像有点大,而且没逼格。。。
想啊想啊想,能不能在执行Jedis方法的时候加上我们的代码呢?比如在之前获取连接池中的实例,在之后释放资源。
咦,好像aop可以实现啊。
但是我就想用Java8的Lambda装装逼。
首先,我们看下这个Java内置的函数式接口中的apply方法,解释为“将给定的参数应用于该函数”。
可以,正是我们需要的。
开始愉快的编码吧。
第一步:
创建一个Maven工程,指定编译版本和运行版本为jdk1.8,加入jedis依赖。
第二步:
编写Jedis配置类。
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;
}
}
第三步:
编写执行器
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);
}
}
好像代码也没简化多少。
本文代码
:( 装了逼赶紧逃。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。