• 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也还须要做一些优化,优化将在下一篇博客讲!
             

  • 相关阅读:
    作业3-2
    作业3-1
    习题二(8)
    习题二(7)
    习题二(6)
    习题二(5)
    习题二(4)
    实验2-2
    实验2
    第二章 例题2-11
  • 原文地址:https://www.cnblogs.com/tlnshuju/p/6943225.html
Copyright © 2020-2023  润新知