美文网首页
自己写的CacheAble和CacheEvict

自己写的CacheAble和CacheEvict

作者: cxjhihihi | 来源:发表于2017-06-01 15:51 被阅读0次

    引言:

    之前在开发中,使用了spring-redis-data中的@CacheAble和@CacheEvict,但是在使用过程中发现,存在key串掉或失效的情况,同时,在redis客户端直接 get key查询时,并不是直接返回value,因此,抽空自己写了这个注解。

    思路:

    使用了jedis客户端,然后再用aop切入service所有使用缓存的方法,缓存数据至redis

    代码:
    1、spring-redis.xml

    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxTotal" value="300" />
        <property name="maxIdle" value="50" />
        <property name="minIdle" value="1" />
        <property name="maxWaitMillis" value="3000" />
        <property name="testOnBorrow" value="true" />
    </bean>
    <!-- jedis pool配置 -->
    <!-- redis的连接池pool,不是必选项:timeout/password -->
    <bean id="jedisPool" class="redis.clients.jedis.JedisPool">
        <constructor-arg index="0" ref="jedisPoolConfig" />
        <constructor-arg index="1" value="${redishost}" />
        <constructor-arg index="2" value="${redisport}" type="int" />
        <constructor-arg index="3" value="300000" type="int" />
        <constructor-arg index="4" value="${redispwd}"></constructor-arg>
    </bean>
    <bean id="redisCache" class="com.netease.mail.vip.commenta.service.redis.RedisCache">
        <property name="jedisPool" ref="jedisPool"></property>
    </bean>
    

    2、RedisCache.java

    public class RedisCache {
    
        private JedisPool jedisPool;
    
        public JedisPool getJedisPool() {
            return jedisPool;
        }
    
        public void setJedisPool(JedisPool jedisPool) {
            this.jedisPool = jedisPool;
        }
    
        public void set(String key, Object value, int seconds) {
            Jedis jedis = null;
            try {
                jedis = jedisPool.getResource();
                jedis.set(key, String.valueOf(value));
                jedis.expire(key, seconds);
            } catch (Exception e) {
                e.printStackTrace();
                if (jedis != null) {
                    jedisPool.returnBrokenResource(jedis);
                }
            } finally {
                if (jedis != null) {
                    jedisPool.returnResource(jedis);
                }
            }
        }
    
        public void set(String key, Object value) {
            set(key, value, 3600);
        }
    
        public String get(String key) {
            Jedis jedis = null;
            try {
                jedis = jedisPool.getResource();
                String value = jedis.get(key);
                return value;
            } catch (Exception e) {
                e.printStackTrace();
                if (jedis != null) {
                    jedisPool.returnBrokenResource(jedis);
                }
                return null;
            } finally {
                if (jedis != null) {
                    jedisPool.returnResource(jedis);
                }
            }
    
        }
    
        public void del(String key) {
            Jedis jedis = null;
            try {
                jedis = jedisPool.getResource();
                jedis.del(key);
            } catch (Exception e) {
                e.printStackTrace();
                if (jedis != null) {
                    jedisPool.returnBrokenResource(jedis);
                }
            } finally {
                if (jedis != null) {
                    jedisPool.returnResource(jedis);
                }
            }
    
        }
    
        public Object getObject(String key) {
            Jedis jedis = null;
            try {
                jedis = jedisPool.getResource();
                byte[] value = jedis.get(key.getBytes());
                return SerializeUtil.unserialize(value);
            } catch (Exception e) {
                e.printStackTrace();
                if (jedis != null) {
                    jedisPool.returnBrokenResource(jedis);
                }
                return null;
            } finally {
                if (jedis != null) {
                    jedisPool.returnResource(jedis);
                }
            }
    
        }
    
        public void setObject(String key, Object value, Integer seconds) {
            Jedis jedis = null;
            try {
                jedis = jedisPool.getResource();
                jedis.set(key.getBytes(), SerializeUtil.serialize(value));
                jedis.expire(key.getBytes(), seconds);
            } catch (Exception e) {
                e.printStackTrace();
                if (jedis != null) {
                    jedisPool.returnBrokenResource(jedis);
                }
            } finally {
                if (jedis != null) {
                    jedisPool.returnResource(jedis);
                }
            }
    
        }
    
        public void setObject(String key, Object value) {
            Jedis jedis = null;
            try {
                jedis = jedisPool.getResource();
                jedis.set(key.getBytes(), SerializeUtil.serialize(value));
            } catch (Exception e) {
                e.printStackTrace();
                if (jedis != null) {
                    jedisPool.returnBrokenResource(jedis);
                }
            } finally {
                if (jedis != null) {
                    jedisPool.returnResource(jedis);
                }
            }
    
        }
        
        public void delObject(String key) {
            Jedis jedis = null;
            try {
                jedis = jedisPool.getResource();
                jedis.del(key.getBytes());
            } catch (Exception e) {
                e.printStackTrace();
                if (jedis != null) {
                    jedisPool.returnBrokenResource(jedis);
                }
            } finally {
                if (jedis != null) {
                    jedisPool.returnResource(jedis);
                }
            }
        }
    }
    

    SerializeUtil.java

    public class SerializeUtil {
          public static byte[] serialize(Object object) {
               ObjectOutputStream oos = null;
                ByteArrayOutputStream baos = null;
                try {
                     // 序列化
                    baos = new ByteArrayOutputStream();
                    oos = new ObjectOutputStream(baos);
                    oos.writeObject(object);
                     byte[] bytes = baos.toByteArray();
                     return bytes;
               } catch (Exception e) {
    
               }
                return null;
         }
    
          public static Object unserialize( byte[] bytes) {
               ByteArrayInputStream bais = null;
                try {
                     // 反序列化
                    bais = new ByteArrayInputStream(bytes);
                    ObjectInputStream ois = new ObjectInputStream(bais);
                     return ois.readObject();
               } catch (Exception e) {
    
               }
                return null;
         }
    }
    

    @CacheAble

    @Target({ ElementType.METHOD, ElementType.TYPE })
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    @Documented
    public @interface Cacheable{
    
        public static String DEFAULT_KEY = "d_key";
    
        /**
         * 前缀标志位
         * 
         * @return
         */
        @AliasFor("value")
        public abstract String value() default "default_prefix";
    
        /**
         * 当key为空,或非#开头,或没有该参数,则将这个注解对应的方法名作为key,否则以数#标志位,从1开始
         * 
         * @return
         */
        public abstract String key() default DEFAULT_KEY;
    
        public abstract int expiretime() default 3600;
    
    }
    

    @CacheEvict

    @Target({ ElementType.METHOD, ElementType.TYPE })
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    @Documented
    public @interface CacheEvict {
        
        public static String DEFAULT_KEY = "d_key";
    
        /**
         * 前缀标志位
         * 
         * @return
         */
        @AliasFor("value")
        public abstract String value() default "default_prefix";
    
        /**
         * 当key为空,或非#开头,或没有该参数,则默认为无参数(仅存储一个key)
         * 
         * @return
         */
        public abstract String key() default DEFAULT_KEY;
    }
    

    CacheUtils.java

    @Aspect
    @Component
    public class CacheUtils {
    
        static Logger logger = Logger.getLogger(CacheUtils.class);
        @Autowired
        RedisCache redisCache;
    
        @Around(value = "execution (* com.cxjhihihi.service..*Service.*(..)) && @annotation(cache)")
        public Object cacheableMethod(ProceedingJoinPoint pjd, Cacheable cache) throws Throwable {
            Object result = null;
            String key = cache.key();
            String value = cache.value();
            String realKey = getRealKey(pjd, key, value);
            result = redisCache.getObject(realKey.toString());
            if (ObjectUtils.isEmpty(result)) {
                logger.info("[cacheable] key=" + realKey.toString() + " result is null");
                result = pjd.proceed();
                redisCache.setObject(realKey.toString(), result, cache.expiretime());
                logger.info("[cacheable] set cache key=" + realKey.toString() + " expiretime=" + cache.expiretime());
            }
            return result;
        }
    
        @Around(value = "execution (* com.cxjhihihi.service..*Service.*(..)) && @annotation(cache)")
        public void cacheEvitMethod(ProceedingJoinPoint pjd, CacheEvict cache) throws Throwable {
            String key = cache.key();
            String value = cache.value();
            String realKey = getRealKey(pjd, key, value);
            logger.info("[cacheEvict] key=" + realKey.toString());
            redisCache.delObject(realKey.toString());
        }
    
        private String getRealKey(ProceedingJoinPoint pjd, String key, String value)
                throws ClassNotFoundException, NotFoundException {
            logger.info("[cache realkey] key=" + key + " value=" + value);
            Object[] args = pjd.getArgs();
    
            String methodName = pjd.getSignature().getName();
            StringBuffer realKey = new StringBuffer().append(value).append("_");
            if (key.equals(Cacheable.DEFAULT_KEY) || !key.startsWith("#")) {
                realKey.append(methodName);
            } else {
                Integer key_index = Integer.parseInt(key.substring(1)) - 1;
    
                realKey.append(args[key_index]);
            }
            return realKey.toString();
        }
    }
    
    

    相关文章

      网友评论

          本文标题:自己写的CacheAble和CacheEvict

          本文链接:https://www.haomeiwen.com/subject/ssdefxtx.html