上篇博客大概的对Redis做了一个主要的了解。由于刚刚接触自己也不太明确。所以上篇博客写的乱七八糟的。这篇由于项目须要,学习了一下Redis和EJB集成。
如今脑子相对照较清晰了一些。
实现思路
缓存的功能是和业务无关的,为的是提高程序的性能。也就是说能够将程序和缓存看作是两个平行的功能。
那么在这样的情况下就能够借助AOP的思想来将缓存引入到程序中,已实现缓存功能在一个程序中的重用问题。
那么多程序的情况下,这就仅仅能打成jar包引用到各个程序中去了。EJB中没有像spring aop一样的完整的机制,可是能够借助拦截器来实现缓存功能的切入。
这里,EJB容器的作用就是识别拦截标志。然后交给拦截器去处理,拦截器在调用缓存client运行缓存的操作。以下就看看实现。
client的开发
- 引入相关的Jar包(基于maven项目)
<span style="font-family:FangSong_GB2312;font-size:18px;"><span style="font-family:FangSong_GB2312;font-size:18px;"> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.6.2</version> <type>ejb</type> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.0</version> <type>ejb</type> </dependency> <dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>6.0</version> <type>ejb</type> </dependency></span></span>
- 面对Jedis的缓存管理类(RedisManager)
<span style="font-family:FangSong_GB2312;font-size:18px;">private String host = "127.0.0.1"; private int port = 6379; private int expire = 0; private int timeout = 0; private String password = ""; private static JedisPool jedisPool = null; public RdisManager(){ } /** * 初始化方法 */ public void init(){ if(jedisPool == null){ if(password != null && !"".equals(password)){ jedisPool = new JedisPool(new JedisPoolConfig(), host, port, timeout, password); }else if(timeout != 0){ jedisPool = new JedisPool(new JedisPoolConfig(), host, port,timeout); }else{ jedisPool = new JedisPool(new JedisPoolConfig(), host, port); } } } /** * 从redis依据key值取得value * @param key * @return */ public byte[] get(byte[] key){ byte[] value = null; Jedis jedis = jedisPool.getResource(); try{ value = jedis.get(key); }finally{ jedisPool.returnResource(jedis); } return value; } /** * 将value创建一个key值存入redis * @param key * @param value * @return */ public byte[] set(byte[] key,byte[] value){ Jedis jedis = jedisPool.getResource(); try{ jedis.set(key,value); if(this.expire != 0){ jedis.expire(key, this.expire); } }finally{ jedisPool.returnResource(jedis); } return value; } /** * 存入Key-Vlaue键值对和过期时间 * @param key * @param value * @param expire * @return */ public byte[] set(byte[] key,byte[] value,int expire){ Jedis jedis = jedisPool.getResource(); try{ jedis.set(key,value); if(expire != 0){ jedis.expire(key, expire); } }finally{ jedisPool.returnResource(jedis); } return value; } /** * 依据key值删除value * @param key */ public void del(byte[] key){ Jedis jedis = jedisPool.getResource(); try{ jedis.del(key); }finally{ jedisPool.returnResource(jedis); } } /** * 清空当前数据库 */ public void flushDB(){ Jedis jedis = jedisPool.getResource(); try{ jedis.flushDB(); }finally{ jedisPool.returnResource(jedis); } } /** * key值的总数 */ public Long dbSize(){ Long dbSize = 0L; Jedis jedis = jedisPool.getResource(); try{ dbSize = jedis.dbSize(); }finally{ jedisPool.returnResource(jedis); } return dbSize; } /** * keys * @param regex * @return */ public Set<byte[]> keys(String pattern){ Set<byte[]> keys = null; Jedis jedis = jedisPool.getResource(); try{ keys = jedis.keys(pattern.getBytes()); }finally{ jedisPool.returnResource(jedis); } return keys; } public String getHost() { return host; } public void setHost(String host) { this.host = host; } public int getPort() { return port; } public void setPort(int port) { this.port = port; } public int getExpire() { return expire; } public void setExpire(int expire) { this.expire = expire; } public int getTimeout() { return timeout; } public void setTimeout(int timeout) { this.timeout = timeout; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }</span>
- 面对用户的缓存操作类(Cache)
<span style="font-family:FangSong_GB2312;font-size:18px;"><span style="font-family:FangSong_GB2312;font-size:18px;">public class Cache { /** * 持有redis管理器 */ private RedisManager cacheManager=new RedisManager(); /** * @param key * @return * @author 卓家进 * @Date 2015年3月9日下午9:23:59 */ public String get(String key){ byte result[] = cacheManager.get(DataTypeUtils.stringToByte(key)); return DataTypeUtils.btyeToString(result); } /** * key-value相应写入 * @param key值 * @param value缓存数据 * @author 卓家进 * @Date 2015年3月10日下午4:02:39 */ public void set(String key,String value){ cacheManager.set(DataTypeUtils.stringToByte(key), SerializeUtils.serialize(value)); } /** * 依据key值删除缓存 * @param key * @author 卓家进 * @Date 2015年3月10日下午4:12:45 */ public void del(String key){ cacheManager.del(DataTypeUtils.stringToByte(key)); } }</span></span>
这里另一个数据类型转换类,功能是String类型和byte类型之间的转换。这是在键值须要的转换。
Value还须要一个序列化的类来处理。
这个两个类就不贴代码了。
- 拦截器类
<span style="font-family:FangSong_GB2312;font-size:18px;"><span style="font-family:FangSong_GB2312;font-size:18px;">public class CacheInterceptor { private Cache cache=new Cache(); @AroundInvoke public Object cache(InvocationContext ctx) throws Exception{ System.out.println("进入拦截器"); String path = ctx.getTarget().getClass().getResource("").getPath(); XmlProperty xmlpro = XmlProperty.getInstance(); xmlpro.init(path); cache.set("測试", "成功调用"); ctx.proceed(); System.out.println(cache.get("測试")); String flag="调用成功"; return flag; } }</span></span>
这样,缓存client的开发以及须要和EJB结合的拦截器类就都能够了。须要用到缓存的项目仅仅要将jar包引入,让后在拦截器的注解上指明这里写的拦截器类就能够使用了。当然。上面仅仅是一个样例。缓存的Key值生成策略还没有考虑清楚,所以临时还不能用作缓存。
这个client也还须要做一些优化,优化将在下一篇博客讲!