Redis+EJB实现缓存(一)

    上篇博客大概的对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)
    这个类,包含与redis数据库的链接的创建和管理,以及对数据存储操作。这个类的操作的都是byte型的数据。因此还须要封装一层面对使用者相对有好的缓存管理类。
<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也还须要做一些优化,优化将在下一篇博客讲!
         

原文地址:https://www.cnblogs.com/tlnshuju/p/6943225.html