spring-data-redis时效设置

本人转自http://hbxflihua.iteye.com/blog/2320584#bc2396403

spring目前在@Cacheable和@CacheEvict等注解上不支持缓存时效设置,只允许通过配置文件设置全局时效。这样就很不方便设定时间。比如系统参数和业务数据的时效是不一样的,这给程序开发造成很大的困扰。不得已,我重写了spring的这两个注解。以下是具体实现。

首先定义@Cacheable和@CacheEvict注解类。

Java代码   收藏代码
  1. package com.lh.common.annotation;  
  2.   
  3. import java.lang.annotation.ElementType;  
  4. import java.lang.annotation.Retention;  
  5. import java.lang.annotation.RetentionPolicy;  
  6. import java.lang.annotation.Target;  
  7.   
  8. import com.rd.ifaes.common.dict.ExpireTime;  
  9. @Retention(RetentionPolicy.RUNTIME)    
  10. @Target({ElementType.METHOD})   
  11. public @interface Cacheable {  
  12.   
  13.     public String key() default ""; // 缓存key  
  14.   
  15.     public ExpireTime expire() default ExpireTime.NONE; // 缓存时效,默认无限期  
  16.   
  17. }  
Java代码   收藏代码
  1. package com.lh.common.annotation;  
  2.   
  3. import java.lang.annotation.Documented;  
  4. import java.lang.annotation.ElementType;  
  5. import java.lang.annotation.Inherited;  
  6. import java.lang.annotation.Retention;  
  7. import java.lang.annotation.RetentionPolicy;  
  8. import java.lang.annotation.Target;  
  9. /** 
  10.  * 缓存清除 
  11.  * @author lh 
  12.  * @version 3.0 
  13.  * @since 2016-8-28 
  14.  * 
  15.  */  
  16. @Target({ ElementType.METHOD })  
  17. @Retention(RetentionPolicy.RUNTIME)  
  18. @Inherited  
  19. @Documented  
  20. public @interface CacheEvict {  
  21.   
  22.     String key() default "";// 缓存key  
  23.       
  24. }  

具体的切面代码(CacheAspect.java)如下:

Java代码   收藏代码
  1. package com.lh.common.annotation;  
  2.   
  3. import java.util.List;  
  4. import java.util.Set;  
  5. import java.util.concurrent.TimeUnit;  
  6.   
  7. import org.aspectj.lang.ProceedingJoinPoint;  
  8. import org.aspectj.lang.annotation.Around;  
  9. import org.aspectj.lang.annotation.Aspect;  
  10. import org.springframework.beans.factory.annotation.Autowired;  
  11. import org.springframework.data.redis.core.RedisTemplate;  
  12. import org.springframework.data.redis.core.ValueOperations;  
  13. import org.springframework.stereotype.Component;  
  14. import org.springframework.util.CollectionUtils;  
  15.   
  16. import com.rd.ifaes.common.util.ReflectionUtils;  
  17. import com.rd.ifaes.common.util.StringUtils;  
  18. import com.rd.ifaes.core.core.util.CacheUtils;  
  19.   
  20. @Aspect  
  21. @Component  
  22. public class CacheAspect {  
  23.   
  24.     @SuppressWarnings("rawtypes")  
  25.     @Autowired  
  26.     private RedisTemplate redisTemplate;  
  27.   
  28.     @Around("@annotation(cache)")  
  29.     public Object cacheable(final ProceedingJoinPoint pjp, Cacheable cache) throws Throwable {  
  30.   
  31.         String key = getCacheKey(pjp, cache.key());  
  32. //       //方案一:使用自定义缓存工具类操作缓存  
  33. //       Object value = CacheUtils.getObj(key);// 从缓存获取数据  
  34. //       if (value != null) {  
  35. //       return value; // 如果有数据,则直接返回  
  36. //       }  
  37. //       value = pjp.proceed(); // 缓存,到后端查询数据  
  38. //       if (value != null) {  
  39. //       CacheUtils.set(key, value, cache.expire());  
  40. //       }  
  41.   
  42.         // 方案二:使用redisTemplate操作缓存  
  43.         @SuppressWarnings("unchecked")  
  44.         ValueOperations<String, Object> valueOper = redisTemplate.opsForValue();  
  45.         Object value =  valueOper.get(key); // 从缓存获取数据  
  46.         if (value != null) {  
  47.             return value; // 如果有数据,则直接返回  
  48.         }  
  49.           
  50.         value = pjp.proceed(); // 缓存,到后端查询数据  
  51.         CacheUtils.set(key, value, cache.expire());  
  52.         if (cache.expire().getTime() <= 0) { // 如果没有设置过期时间,则无限期缓存  
  53.             valueOper.set(key, value);  
  54.         } else { // 否则设置缓存时间  
  55.             valueOper.set(key, value, cache.expire().getTime(), TimeUnit.SECONDS);  
  56.         }  
  57.         return value;  
  58.     }  
  59.       
  60.     @SuppressWarnings("unchecked")  
  61.     @Around("@annotation(evict)")  
  62.     public Object cacheEvict(final ProceedingJoinPoint pjp, CacheEvict evict) throws Throwable {  
  63.         Object value = pjp.proceed(); // 执行方法  
  64.         String key = getCacheKey(pjp, evict.key());  
  65. //       //方案一:使用自定义缓存工具类操作缓存  
  66. //       CacheUtils.del(key);  
  67.   
  68.         // 方案二:使用redisTemplate操作缓存  
  69.         if (evict.key().equals(key)) {// 支持批量删除  
  70.             Set<String> keys = redisTemplate.keys(key.concat("*"));  
  71.             redisTemplate.delete(keys);  
  72.         }else{  
  73.             redisTemplate.delete(key);            
  74.         }  
  75.         return value;  
  76.     }  
  77.       
  78.   
  79.     /** 
  80.      * 获取缓存的key值 
  81.      *  
  82.      * @param pjp 
  83.      * @param key 
  84.      * @return 
  85.      */  
  86.     private String getCacheKey(ProceedingJoinPoint pjp, String key) {  
  87.   
  88.         StringBuilder buf = new StringBuilder();  
  89.         Object[] args = pjp.getArgs();  
  90.           
  91.         if(StringUtils.isNotBlank(key)){  
  92.             buf.append(key);  
  93.             List<String> annoParamNames = AopUtils.getAnnoParams(key);  
  94.             String[] methodParamNames = AopUtils.getMethodParamNames(AopUtils.getMethod(pjp));  
  95.             if(!CollectionUtils.isEmpty(annoParamNames)){  
  96.                 for (String ap : annoParamNames) {  
  97.                     String paramValue = "";  
  98.                     for (int i = 0; i < methodParamNames.length; i++) {  
  99.                         if(ap.startsWith(methodParamNames[i])){  
  100.                             Object arg = args[i];  
  101.                             if (ap.contains(".")) {  
  102.                                 paramValue = String.valueOf(ReflectionUtils.invokeGetter(arg, ap.substring(ap.indexOf(".") + 1)));  
  103.                             } else {  
  104.                                 paramValue = String.valueOf(arg);  
  105.                             }  
  106.                         }  
  107.                     }  
  108.                     int start = buf.indexOf("{" + ap);  
  109.                     int end = start + ap.length() + 2;  
  110.                     buf = buf.replace(start, end, paramValue);  
  111.                 }                 
  112.             }  
  113.               
  114.         }else{  
  115.             buf.append(pjp.getSignature().getDeclaringTypeName()).append(":").append(pjp.getSignature().getName());  
  116.             for (Object arg : args) {  
  117.                 buf.append(":").append(arg.toString());  
  118.             }  
  119.         }     
  120.   
  121.         return buf.toString();  
  122.     }  
  123. }  

里面使用到AopUtils.java和ExpireTime.java两个类,具体代码如下:

Java代码   收藏代码
  1. package com.lh.common.annotation;  
  2.   
  3. import org.aspectj.lang.ProceedingJoinPoint;  
  4. import org.aspectj.lang.Signature;  
  5. import org.aspectj.lang.reflect.MethodSignature;  
  6. import org.springframework.asm.*;  
  7.   
  8. import java.io.IOException;  
  9. import java.io.InputStream;  
  10. import java.lang.reflect.Method;  
  11. import java.lang.reflect.Modifier;  
  12. import java.util.ArrayList;  
  13. import java.util.List;  
  14. import java.util.regex.Matcher;  
  15. import java.util.regex.Pattern;  
  16.   
  17. /** 
  18.  * 切面编程工具类 
  19.  * @author lh 
  20.  * @version 3.0 
  21.  * @since 2016-8-26 
  22.  */  
  23. public class AopUtils {  
  24.   
  25.       
  26.   
  27.     /** 
  28.      * <p>获取方法的参数名</p> 
  29.      * 
  30.      * @param m 
  31.      * @return 
  32.      */  
  33.     public static String[] getMethodParamNames(final Method m) {  
  34.         final String[] paramNames = new String[m.getParameterTypes().length];  
  35.         final String n = m.getDeclaringClass().getName();  
  36.         final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);  
  37.         String className = m.getDeclaringClass().getSimpleName();  
  38.         ClassReader cr = null;  
  39.         InputStream resourceAsStream = null;  
  40.         try {  
  41. //          cr = new ClassReader(n);  
  42. //          String filePathName = Class.forName(n).getResource("EDayHqbProcessManagerImpl.class").getPath();  
  43.             resourceAsStream = Class.forName(n).getResourceAsStream(className + ".class");  
  44.             cr = new ClassReader(resourceAsStream);  
  45. //          cr = new ClassReader(ClassLoader.getSystemResourceAsStream(n + ".class"));  
  46.         } catch (IOException e) {  
  47.             //e.printStackTrace();  
  48. //          Exceptions.uncheck(e);  
  49.         } catch (ClassNotFoundException e) {  
  50.             //e.printStackTrace();  
  51.         } finally {  
  52.             if (resourceAsStream != null) {  
  53.                 try {  
  54.                     resourceAsStream.close();  
  55.                 } catch (IOException e) {  
  56.                     e.printStackTrace();  
  57.                 }  
  58.             }  
  59.         }  
  60.         assert cr != null;  
  61.         cr.accept(new ClassVisitor(Opcodes.ASM4, cw) {  
  62.             @Override  
  63.             public MethodVisitor visitMethod(final int access,  
  64.                                              final String name, final String desc,  
  65.                                              final String signature, final String[] exceptions) {  
  66.                 final Type[] args = Type.getArgumentTypes(desc);  
  67.                 // 方法名相同并且参数个数相同  
  68.                 if (!name.equals(m.getName())  
  69.                         || !sameType(args, m.getParameterTypes())) {  
  70.                     return super.visitMethod(access, name, desc, signature,  
  71.                             exceptions);  
  72.                 }  
  73.                 MethodVisitor v = cv.visitMethod(access, name, desc, signature,  
  74.                         exceptions);  
  75.                 return new MethodVisitor(Opcodes.ASM4, v) {  
  76.                     @Override  
  77.                     public void visitLocalVariable(String name, String desc,  
  78.                                                    String signature, Label start, Label end, int index) {  
  79.                         int i = index - 1;  
  80.                         // 如果是静态方法,则第一就是参数  
  81.                         // 如果不是静态方法,则第一个是"this",然后才是方法的参数  
  82.                         if (Modifier.isStatic(m.getModifiers())) {  
  83.                             i = index;  
  84.                         }  
  85.                         if (i >= 0 && i < paramNames.length) {  
  86.                             paramNames[i] = name;  
  87.                         }  
  88.                         super.visitLocalVariable(name, desc, signature, start,  
  89.                                 end, index);  
  90.                     }  
  91.   
  92.                 };  
  93.             }  
  94.         }, 0);  
  95.   
  96.         return paramNames;  
  97.     }  
  98.   
  99.   
  100.     /** 
  101.      * <p>比较参数类型是否一致</p> 
  102.      * 
  103.      * @param types   asm的类型({@link Type}) 
  104.      * @param clazzes java 类型({@link Class}) 
  105.      * @return 
  106.      */  
  107.     private static boolean sameType(Type[] types, Class<?>[] clazzes) {  
  108.         // 个数不同  
  109.         if (types.length != clazzes.length) {  
  110.             return false;  
  111.         }  
  112.   
  113.         for (int i = 0; i < types.length; i++) {  
  114.             if (!Type.getType(clazzes[i]).equals(types[i])) {  
  115.                 return false;  
  116.             }  
  117.         }  
  118.         return true;  
  119.     }  
  120.       
  121.     /** 
  122.      * 取得切面调用的方法 
  123.      * @param pjp 
  124.      * @return 
  125.      */  
  126.     public static Method getMethod(ProceedingJoinPoint pjp){  
  127.         Signature sig = pjp.getSignature();  
  128.         MethodSignature msig = null;  
  129.         if (!(sig instanceof MethodSignature)) {  
  130.             throw new IllegalArgumentException("该注解只能用于方法");  
  131.         }  
  132.         msig = (MethodSignature) sig;  
  133.         Object target = pjp.getTarget();  
  134.         Method currentMethod = null;  
  135.         try {  
  136.             currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());  
  137.         } catch (NoSuchMethodException e) {  
  138.         } catch (SecurityException e) {  
  139.         }          
  140.         return currentMethod;  
  141.     }  
  142.       
  143.     public static List<String> getMatcher(String regex, String source) {    
  144.         List<String> list = new ArrayList<String>();  
  145.         Pattern pattern = Pattern.compile(regex);    
  146.         Matcher matcher = pattern.matcher(source);    
  147.         while (matcher.find()) {    
  148.             list.add(matcher.group());  
  149.         }    
  150.         return list;    
  151.     }  
  152.       
  153.     /** 
  154.      * 取得注解参数 
  155.         (?=exp) 匹配exp前面的位置 
  156.         (?<=exp) 匹配exp后面的位置 
  157.         (?!exp) 匹配后面跟的不是exp的位置 
  158.         (?<!exp) 匹配前面不是exp的位置 
  159.      * @param managers 
  160.      * @return 
  161.      */  
  162.     public static List<String> getAnnoParams(String source){  
  163.         String regex = "(?<=\\{)(.+?)(?=\\})";  
  164.         return getMatcher(regex, source);  
  165.     }  
  166.       
  167.   
  168. }  
Java代码   收藏代码
  1. package com.lh.common.dict;  
  2.   
  3. /** 
  4.  * 失效时间枚举类 
  5.  * @author lh 
  6.  * @version 3.0 
  7.  * @since 2016-8-25 
  8.  * 
  9.  */  
  10. public enum ExpireTime {  
  11.       
  12.     /** 
  13.      * 无固定期限 
  14.      */  
  15.     NONE(0, "无固定期限")  
  16.       
  17.     /** 
  18.      * 1秒钟 
  19.      */  
  20.     ,ONE_SEC(1, "1秒钟")  
  21.   
  22.     /** 
  23.      * 5秒钟 
  24.      */  
  25.     ,FIVE_SEC(5, "5秒钟")  
  26.   
  27.     /** 
  28.      * 10秒钟 
  29.      */  
  30.     ,TEN_SEC(10, "10秒钟")  
  31.   
  32.     /** 
  33.      * 30秒钟 
  34.      */  
  35.     ,HALF_A_MIN(30, "30秒钟")  
  36.   
  37.     /** 
  38.      * 1分钟 
  39.      */  
  40.     ,ONE_MIN(60, "1分钟")  
  41.   
  42.     /** 
  43.      * 5分钟 
  44.      */  
  45.     ,FIVE_MIN(5 * 60, "5分钟")  
  46.   
  47.     /** 
  48.      * 10分钟 
  49.      */  
  50.     ,TEN_MIN(10 * 60, "10分钟")  
  51.       
  52.     /** 
  53.      * 20分钟 
  54.      */  
  55.     ,TWENTY_MIN(20 * 60, "20分钟")  
  56.   
  57.     /** 
  58.      * 30分钟 
  59.      */  
  60.     ,HALF_AN_HOUR(30 * 60, "30分钟")  
  61.   
  62.     /** 
  63.      * 1小时 
  64.      */  
  65.     ,ONE_HOUR(60 * 60, "1小时")  
  66.   
  67.     /** 
  68.      * 1天 
  69.      */  
  70.     ,ONE_DAY(24 * 60 * 60, "1天")  
  71.   
  72.     /** 
  73.      * 1个月 
  74.      */  
  75.     ,ONE_MON(30 * 24 * 60 * 60, "1个月")  
  76.   
  77.     /** 
  78.      * 1年 
  79.      */  
  80.     ,ONE_YEAR(365 * 24 * 60 * 60, "1年")  
  81.   
  82.     ;  
  83.       
  84.     /** 
  85.      * 时间 
  86.      */  
  87.     private final int time;  
  88.     /** 
  89.      * 描述 
  90.      */  
  91.     private final String desc;  
  92.       
  93.     ExpireTime(int time, String desc) {  
  94.         this.time = time;  
  95.         this.desc = desc;  
  96.     }  
  97.   
  98.       
  99.     /** 
  100.      * 获取具体时间 
  101.      * @return 
  102.      */  
  103.     public int getTime() {  
  104.         return time;  
  105.     }  
  106.   
  107.     /** 
  108.      * 获取时间描述信息 
  109.      * @return 
  110.      */  
  111.     public String getDesc() {  
  112.         return desc;  
  113.     }  
  114.       
  115.     /** 
  116.      * 根据时间匹配失效期限 
  117.      * @param time 
  118.      * @return 
  119.      */  
  120.     public static ExpireTime match(int time){  
  121.         if(NONE.getTime() == time){  
  122.             return NONE;  
  123.         }else if(ONE_SEC.getTime() ==  time){  
  124.             return ONE_SEC;  
  125.         }else if(FIVE_SEC.getTime() ==  time){  
  126.             return FIVE_SEC;  
  127.         }else if(TEN_SEC.getTime() ==  time){  
  128.             return TEN_SEC;  
  129.         }else if(HALF_A_MIN.getTime() ==  time){  
  130.             return HALF_A_MIN;  
  131.         }else if(ONE_MIN.getTime() ==  time){  
  132.             return ONE_MIN;  
  133.         }else if(FIVE_MIN.getTime() ==  time){  
  134.             return FIVE_MIN;  
  135.         }else if(TEN_MIN.getTime() ==  time){  
  136.             return TEN_MIN;  
  137.         }else if(TWENTY_MIN.getTime() == time){  
  138.             return TWENTY_MIN;  
  139.         }else if(HALF_AN_HOUR.getTime() ==  time){  
  140.             return HALF_AN_HOUR;  
  141.         }else if(ONE_HOUR.getTime() ==  time){  
  142.             return ONE_HOUR;  
  143.         }else if(ONE_DAY.getTime() ==  time){  
  144.             return ONE_DAY;  
  145.         }else if(ONE_MON.getTime() ==  time){  
  146.             return ONE_MON;  
  147.         }else if(ONE_YEAR.getTime() ==  time){  
  148.             return ONE_YEAR;  
  149.         }  
  150.         return HALF_AN_HOUR;  
  151.     }  
  152.       
  153. }  

  配置中的RdRedisCache.java 代码如下:

Java代码   收藏代码
  1. package com.lh.common.jedis;  
  2.   
  3. import java.io.ByteArrayInputStream;  
  4. import java.io.ByteArrayOutputStream;  
  5. import java.io.IOException;  
  6. import java.io.ObjectInputStream;  
  7. import java.io.ObjectOutputStream;  
  8.   
  9. import net.sf.ehcache.Element;  
  10.   
  11. import org.springframework.cache.Cache;  
  12. import org.springframework.cache.support.SimpleValueWrapper;  
  13. import org.springframework.dao.DataAccessException;  
  14. import org.springframework.data.redis.connection.RedisConnection;  
  15. import org.springframework.data.redis.core.RedisCallback;  
  16. import org.springframework.data.redis.core.RedisTemplate;  
  17.   
  18. public class RdRedisCache implements Cache {  
  19.   
  20.     private RedisTemplate<String, Object> redisTemplate;  
  21.     private String name;  
  22.   
  23.     public RedisTemplate<String, Object> getRedisTemplate() {  
  24.         return redisTemplate;  
  25.     }  
  26.   
  27.     public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {  
  28.         this.redisTemplate = redisTemplate;  
  29.     }  
  30.   
  31.     public void setName(String name) {  
  32.         this.name = name;  
  33.     }  
  34.   
  35.     @Override  
  36.     public String getName() {  
  37.         return this.name;  
  38.     }  
  39.   
  40.     @Override  
  41.     public Object getNativeCache() {  
  42.         return this.redisTemplate;  
  43.     }  
  44.   
  45.     @Override  
  46.     public ValueWrapper get(Object key) {  
  47.           
  48.         final String keyf = obj2Str(key);  
  49.         Object object = null;  
  50.         object = redisTemplate.execute(new RedisCallback<Object>() {  
  51.             public Object doInRedis(RedisConnection connection)  
  52.                     throws DataAccessException {  
  53.   
  54.                 byte[] key = keyf.getBytes();  
  55.                 byte[] value = connection.get(key);  
  56.                 if (value == null) {  
  57.                     return null;  
  58.                 }  
  59.                 return toObject(value);  
  60.   
  61.             }  
  62.         });  
  63.         return (object != null ? new SimpleValueWrapper(object) : null);  
  64.     }  
  65.   
  66.     @Override  
  67.     public void put(Object key, Object value) {  
  68.           
  69.         final String keyf = obj2Str(key);  
  70.         final Object valuef = value;  
  71.         final long liveTime = 86400;  
  72.   
  73.         redisTemplate.execute(new RedisCallback<Long>() {  
  74.             public Long doInRedis(RedisConnection connection)  
  75.                     throws DataAccessException {  
  76.                 byte[] keyb = keyf.getBytes();  
  77.                 byte[] valueb = toByteArray(valuef);  
  78.                 connection.set(keyb, valueb);  
  79.                 if (liveTime > 0) {  
  80.                     connection.expire(keyb, liveTime);  
  81.                 }  
  82.                 return 1L;  
  83.             }  
  84.         });  
  85.     }  
  86.       
  87.     public String obj2Str(Object key){  
  88.         String keyStr = null;  
  89.         if(key instanceof Integer){  
  90.             keyStr = ((Integer)key).toString();  
  91.         }else if(key instanceof Long){  
  92.             keyStr = ((Long)key).toString();  
  93.         }else {  
  94.             keyStr = (String)key;  
  95.         }  
  96.         return keyStr;  
  97.     }  
  98.   
  99.     /** 
  100.      * 描述 : <Object转byte[]>. <br> 
  101.      * <p> 
  102.      * <使用方法说明> 
  103.      * </p> 
  104.      *  
  105.      * @param obj 
  106.      * @return 
  107.      */  
  108.     private byte[] toByteArray(Object obj) {  
  109.         byte[] bytes = null;  
  110.         ByteArrayOutputStream bos = new ByteArrayOutputStream();  
  111.         try {  
  112.             ObjectOutputStream oos = new ObjectOutputStream(bos);  
  113.             oos.writeObject(obj);  
  114.             oos.flush();  
  115.             bytes = bos.toByteArray();  
  116.             oos.close();  
  117.             bos.close();  
  118.         } catch (IOException ex) {  
  119.             ex.printStackTrace();  
  120.         }  
  121.         return bytes;  
  122.     }  
  123.   
  124.     /** 
  125.      * 描述 : <byte[]转Object>. <br> 
  126.      * <p> 
  127.      * <使用方法说明> 
  128.      * </p> 
  129.      *  
  130.      * @param bytes 
  131.      * @return 
  132.      */  
  133.     private Object toObject(byte[] bytes) {  
  134.         Object obj = null;  
  135.         try {  
  136.             ByteArrayInputStream bis = new ByteArrayInputStream(bytes);  
  137.             ObjectInputStream ois = new ObjectInputStream(bis);  
  138.             obj = ois.readObject();  
  139.             ois.close();  
  140.             bis.close();  
  141.         } catch (IOException ex) {  
  142.             ex.printStackTrace();  
  143.         } catch (ClassNotFoundException ex) {  
  144.             ex.printStackTrace();  
  145.         }  
  146.         return obj;  
  147.     }  
  148.   
  149.     @Override  
  150.     public void evict(Object key) {  
  151.         final String keyf = obj2Str(key);  
  152.         redisTemplate.execute(new RedisCallback<Long>() {  
  153.             public Long doInRedis(RedisConnection connection)  
  154.                     throws DataAccessException {  
  155.                 return connection.del(keyf.getBytes());  
  156.             }  
  157.         });  
  158.     }  
  159.   
  160.     @Override  
  161.     public void clear() {  
  162.         redisTemplate.execute(new RedisCallback<String>() {  
  163.             public String doInRedis(RedisConnection connection)  
  164.                     throws DataAccessException {  
  165.                 connection.flushDb();  
  166.                 return "ok";  
  167.             }  
  168.         });  
  169.     }  
  170.   
  171.     @Override  
  172.     public <T> T get(Object key, Class<T> type) {  
  173.         ValueWrapper wrapper = get(key);  
  174.         return wrapper == null ? null : (T) wrapper.get();  
  175.     }  
  176.   
  177.     @Override  
  178.     public ValueWrapper putIfAbsent(Object key, Object value) {  
  179.         synchronized (key) {  
  180.             ValueWrapper wrapper = get(key);  
  181.             if (wrapper != null) {  
  182.                 return wrapper;  
  183.             }  
  184.             put(key, value);  
  185.             return toWrapper(new Element(key, value));  
  186.         }  
  187.     }  
  188.       
  189.     private ValueWrapper toWrapper(Element element) {  
  190.         return (element != null ? new SimpleValueWrapper(element.getObjectValue()) : null);  
  191.     }  
  192.   
  193. }  

  spring配置文件的相关配置如下:

Xml代码   收藏代码
  1.     <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">  
  2.     <property name="maxIdle" value="${redis.pool.maxIdle}" /> <!-- 最大能够保持idel状态的对象数  -->  
  3.     <property name="maxTotal" value="${redis.pool.maxTotal}" /> <!-- 最大分配的对象数 -->  
  4.     <property name="testOnBorrow" value="${redis.pool.testOnBorrow}" /> <!-- 当调用borrow Object方法时,是否进行有效性检查 -->  
  5. </bean>  
  6.   
  7. <!-- jedisPool init -->  
  8. <bean id="jedisPool" class="redis.clients.jedis.JedisPool">  
  9.     <constructor-arg index="0" ref="jedisPoolConfig" />  
  10.     <constructor-arg index="1" value="${redis.host}" type="String" />  
  11.     <constructor-arg index="2" value="${redis.port}" type="int" />  
  12. </bean>  
  13.   
  14.     <!-- jedis单机配置 -->  
  15.     <bean id="jedisConnFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >  
  16.         <property name="hostName" value="${redis.host}" />  
  17.         <property name="port" value="${redis.port1}" />  
  18.         <property name="timeout" value="${redis.timeout}" />  
  19.         <property name="poolConfig" ref="jedisPoolConfig" />  
  20.     </bean>  
  21.       
  22. <bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" />  
  23.    
  24. <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"  
  25.  p:connectionFactory-ref="jedisConnFactory" p:keySerializer-ref="stringRedisSerializer" />  
  26.       
  27. <!-- spring自己的缓存管理器 -->    
  28.    <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">    
  29.        <property name="caches">    
  30.            <set>    
  31.             <bean class="com.lh.common.jedis.RdRedisCache" p:redis-template-ref="redisTemplate" p:name="sysCache"/>   
  32.            </set>    
  33.        </property>    
  34.    </bean>    
  35.   
  36. <!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 -->  
  37. <cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true" />  

猜你喜欢

转载自www.cnblogs.com/zeussbook/p/9296884.html