在Nutz项目中需要用到Redis,其实网上已经有很多例子的了,特别是Wendal官方cookbook还有示例,但这毕竟不想操作数据库那么通用,已经有成熟的Dao系列包可用,对应Redis丰富的数据结构,和各种应用场景,还是需要自己做一些封装的,这里小结一下项目中的用法。
- 首先,Java客户端肯定要用Jedis,项目中引用了2.8版的包
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.8.0</version> </dependency>
使用maven导入的,也可以直接下载Jar包
-
连接池是Jedis包内置的,池对象作为一个单例存在,当然可以直接new,保存在static变量里,但如果可以注入就更方便了,所以做了一个IoC配置文件:
{ jedis_pool_config : { type : "redis.clients.jedis.JedisPoolConfig", fields : { maxTotal : 10, maxIdle : 5, maxWaitMillis : 30000, testOnBorrow : true } }, jedis_config:{ type: "com.nuanxinli.lib.cache.JedisConfig", fields:{ poolConfig:{ refer : "jedis_pool_config" }, port: 6379, host: "192.168.1.53", timeout: 30000, password:123456 } }, system_jedis_pooler : { type : "com.nuanxinli.lib.cache.JedisPooler", args : [ { refer : "jedis_config" }] } }
注意,JedisPool的API设计,是比较奇怪的,JedisPoolConfig是个配置实体类,里面却不包含host,port这些信息,要想设置IP和端口,只能在构造函数里传参,所以这里又定义了一个JedisConfig类,把需要的其他配置信息补充进去:
@IocBean public class JedisConfig { public JedisPoolConfig poolConfig; public String host; public Integer port; public String password; public Integer timeout; }
新建一个JedisPooler类,作为Pool单例的载体,本打算封装一个类似于Dao的类,后来发现Jedis因为有各种数据结构,方法太多,无法一一封装,还是仅仅做了一个载体类
package com.nuanxinli.lib.cache; import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.json.Json; import org.nutz.log.Log; import org.nutz.log.Logs; import com.nuanxinli.util.StrUtil; import redis.clients.jedis.JedisPool; @IocBean(create = "getPool", depose = "onDepose") public class JedisPooler { private static final Log log = Logs.getLog(JedisPooler.class); private JedisPool pool; JedisConfig config; public JedisPooler(JedisConfig config) { this.config = config; } public synchronized JedisPool getPool() { log.debug("JedisPooler onCreate getPool..."); if (pool == null) { log.debug("即将连接redis:\r\n"+Json.toJson(config)); if (StrUtil.isNotNullOrBlank(config.password)) { pool = new JedisPool(config.poolConfig, config.host, config.port, config.timeout, config.password); } else { pool = new JedisPool(config.poolConfig, config.host, config.port, config.timeout); } } return pool; } public void onDepose() { pool.destroy(); } }
-
这样一个具体的业务类,在使用缓存时,注入JedisPooler对象就可以了,例如
@Inject("refer:system_jedis_pooler") private JedisPooler jedisPooler; public Double add(String username, String providerName, double point) { try (Jedis jedis = jedisPooler.getPool().getResource()) { return jedis.zincrby(KEY_PREFIX+":" + providerName, point, username); } }