zoukankan      html  css  js  c++  java
  • 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" />  
  • 相关阅读:
    微信小程序常用的方法(留着用)
    微信小程序H5预览页面框架(二维码不隐藏)
    微信小程序H5预览页面框架
    关于微信小程序的一点经验
    微信小程序修改单选按钮的默认样式
    Tomcat8升级后URL中特殊字符报错出现原因
    线程的生命周期和状态控制
    多线程相关概率解释
    多线程面试题集锦三
    spring的xml文件的作用与实现原理
  • 原文地址:https://www.cnblogs.com/zeussbook/p/9296884.html
Copyright © 2011-2022 走看看