一,通过函数指针避免try-cath的书写
使用jedis灵活可靠,而且用微不足道的序列化消耗提高开发效率。
首先看一段try-with-resoure风格的jedis片,这种方式jedis会在cath(Excepiton e)或者try代码结束后调用jedis.close()方法
try (Jedis jedis = new Jedis("119.29.111.111", 6379);) {为了减少redis创建和销毁连接的消耗,我们使用jedis池
jedis.select(3);// 选择数据库
// 增
jedis.set("gao", "tia n");// 每次都会覆盖旧的key <gao,tian>
// 查
Logger.getGlobal().info(jedis.get("a"));
} catch (Exception e) {
e.printStackTrace();
}
JedisPool pool = new JedisPool(poolConfig, "119.29.111.111", 6379, 0, "foobared", 3); try (Jedis jedis = pool.getResource()) { } catch (Exception e) { e.printStackTrace(); }pool.close();注意jedis的close方法,会尝试还给自己的jedis池,而不是关闭链接,这里不再赘述。
这样每次try是不是很不方便?
我们可以用一个函数指针,来描述给我一个Jedis对象,我对他进行某些操作,然后返回给我某个类型的值来传入到这个try-with-resource的代码片段里
定义函数指针:
public interface JedisCallBack<T> {定义一个jedis池的包装类
T doInRedis(Jedis jedis) throws DataAccessException;
}
public class JedisPoolHandler {我们接下来看看使用
private JedisPool pool;
...
public <T> T excute(JedisCallBack<T> action){
try (Jedis jedis = pool.getResource()){
return action.doInRedis(jedis);
} catch (Exception e) {
LogCore.BASE.error("jedisHandler err", e);
return null;
}
}
}
long num = handler.excute((jedis) -> jedis.incr(name));是不是很方便?!
二,配置文件和bean的注入
之前的jedis.property
jedis.database=0java文件
jedis.host=localhost
jedis.password=foobared
jedis.port=6379
jedis.timeout=0
public class JedisConfigBase { private int database; private String host; private String password; private int port; private int timeout; ...get,set's methods @Override public String toString() { return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE); }}
@Order(value = 1)@Componentpublic class JedisPoolHandlerInstances implements CommandLineRunner{ @Component //外部tomcat不可以配置为component,嵌入式tomcat需要此注解 @ConfigurationProperties(prefix="jedis",locations="classpath:jedis.properties") public static class JedisConfigStats extends JedisConfigBase{} @Autowired JedisConfigStats stats_jedis_cf; private static JedisPoolHandler STATS_HANDLER; public static JedisPoolHandler getSTATSHandler(){ return STATS_HANDLER; } @Override public void run(String... args) throws Exception { STATS_HANDLER = new JedisPoolHandler(stats_jedis_cf); }}这样写每次都需要getSTATSHander(),不能直接用静态变量STATAS_HANDER,因为别的类的属性在定义时引用的时候,这个对象还没有被Spring注入
但是这样,依然很丑陋。
三,我们重新梳理一下
jedis.properties文件
jedis.database=10
jedis.host=localhost
jedis.auth=foobared
jedis.port=6377
jedis.timeout=0
public interface JedisCallBack<T> {
T doInRedis(Jedis jedis) throws DataAccessException;
}
public class JedisPoolTemplate {
private JedisPool pool;
public JedisPoolTemplate(String host, int port, int timeout, String psw, int database) {
JedisPoolConfig poolConfig = new JedisPoolConfig();
pool = new JedisPool(poolConfig, host, port, timeout, psw, database);
}
public <T> T excute(JedisCallBack<T> action){
try (Jedis jedis = pool.getResource()){
return action.doInRedis(jedis);
} catch (Exception e) {
LogCore.BASE.error("jedisHandler err", e);
return null;
}
}
}
@Configuration@PropertySource("classpath:jedis.properties")public class JedisPoolConfig { @Bean JedisPoolTemplate getJedisPoolTemplate( @Value("${jedis.host}") String host, @Value("${jedis.port}") int port, @Value("${jedis.auth}") String auth, @Value("${jedis.timeout}") int timeout, @Value("${jedis.database}") int database ) { JedisPoolTemplate template = new JedisPoolTemplate(host, port, timeout, auth, database); return template; }}使用方法
@Autowired
JedisPoolTemplate jedisTemplate;
public long incrBy(String name, long value) { return jedisTemplate.excute((jedis) -> jedis.incrBy(name, value)); } public Long zadd(String key, double score, String value) { return jedisTemplate.excute((jedis) -> jedis.zadd(key, score, value)); }
搞掂,嘿嘿