前言
由于这段时间使用SpringBoot的原因,很多东西都用了SpringBoot内部的Template来做,也没关心底层怎么操作的。最近忙里偷闲回答了几个问题,正巧看到一个关于Redis资源释放问题的,引起了我的兴趣,便去看了下官方文档。
Redis推荐的Java客户端是jedis,关于Jedis的配置那些我就不说了,直接上他的示例代码。
/// 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();
也就是说要么用Java7的try-with-resource关闭资源,要么就try finally。
唉,又该有人吐槽Java又臭又长了,像老太婆的裹脚布一样。
怎么办呢?
我们可以写一个方法把所有的redis操作包装起来,里面加上资源释放。
呃?工程量好像有点大,而且没逼格。。。
想啊想啊想,能不能在执行Jedis方法的时候加上我们的代码呢?比如在之前获取连接池中的实例,在之后释放资源。
咦,好像aop可以实现啊。
但是我就想用Java8的Lambda装装逼。
也就是function接口的使用。
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;
}
}
这样try catch finally就直接放到这一个方法中,然后根据不同的业务需要,使用不同的实现代码即可。比如:
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);
}
}