Spring 中使用redis缓存方法记录
Posted rolayblog
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring 中使用redis缓存方法记录相关的知识,希望对你有一定的参考价值。
背景
在平时项目中,可能会有某个条件的查询,会多次进到db里面去查,这样就会重复的查询相同的数据,但是我们的数据又不是需要更改及显示的,这时候就可以用到
方法的缓存了。例如在我们调用微信小程序时,需要获取access_token,并且其有效时间为7200秒,过期后再次获取,我们就可以把获取access_token的方法作为
缓存。以下为我实现的过程记录。
1、重写 RedisSerializer 中的 serialize 和 deserialize
1 public class GenericFastJson2JsonRedisSerializer<T> implements RedisSerializer<T> 2 public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); 3 public GenericFastJson2JsonRedisSerializer() 4 super(); 5 6 @Override 7 public byte[] serialize(T t) throws SerializationException 8 if (t == null) 9 return new byte[0]; 10 11 FastJsonWraper<T> wraperSet =new FastJsonWraper<>(t); 12 return JSON.toJSONString(wraperSet, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET); 13 14 @Override 15 public T deserialize(byte[] bytes) throws SerializationException 16 if (bytes == null || bytes.length <= 0) 17 return null; 18 19 String deserializeStr = new String(bytes, DEFAULT_CHARSET); 20 FastJsonWraper<T> wraperGet=JSON.parseObject(deserializeStr,FastJsonWraper.class); 21 return wraperGet.getValue(); 22 23
2、实现缓存的获取和设置
1 public class RedisCache implements Cache 2 3 private Logger logger = Logger.getLogger(RedisCache.class); 4 private RedisTemplate<String, Object> redisTemplate; 5 6 private String name; 7 8 private String resultType; 9 10 private long expireInSencods; 11 12 public static final String KEY_PREFIX = "wx:"; 13 14 15 @Override 16 public Object getNativeCache() 17 return this.redisTemplate; 18 19 20 21 @Override 22 public ValueWrapper get(Object key) 23 if (logger.isDebugEnabled()) 24 logger.debug("------缓存获取-------" + key.toString()); 25 26 final String keyf = KEY_PREFIX + key.toString(); 27 Object object = null; 28 object = redisTemplate.execute(new RedisCallback<Object>() 29 @Override 30 public Object doInRedis(RedisConnection connection) throws DataAccessException 31 byte[] key = keyf.getBytes(); 32 byte[] value = connection.get(key); 33 if (value == null) 34 if (logger.isDebugEnabled()) 35 logger.debug("------缓存不存在-------"); 36 37 return null; 38 39 try 40 Class<?> class1 = null; 41 if (StringUtils.isNotEmpty(resultType)) 42 class1 = Class.forName(resultType); 43 else 44 class1 = String.class; 45 46 String resultJson = new String(value, Charset.forName("utf-8")); 47 Object result = JSONObject.parseObject(resultJson, class1); 48 return result; 49 catch (ClassNotFoundException e) 50 e.printStackTrace(); 51 52 return null; 53 54 ); 55 ValueWrapper obj = (object != null ? new SimpleValueWrapper(object) : null); 56 if (logger.isDebugEnabled()) 57 logger.debug("------获取到内容-------" + obj); 58 59 return obj; 60 61 62 63 @Override 64 public <T> T get(Object key, Class<T> type) 65 // TODO Auto-generated method stub 66 return null; 67 68 69 70 @Override 71 public <T> T get(Object key, Callable<T> valueLoader) 72 // TODO Auto-generated method stub 73 return null; 74 75 76 77 @Override 78 public void put(Object key, Object value) 79 if (logger.isDebugEnabled()) 80 logger.debug("-------加入缓存------"); 81 logger.debug("key----:" + key); 82 logger.debug("key----:" + value); 83 84 final String keyString = KEY_PREFIX + key.toString(); 85 final Object valuef = value; 86 redisTemplate.execute(new RedisCallback<Long>() 87 @Override 88 public Long doInRedis(RedisConnection connection) throws DataAccessException 89 byte[] keyb = keyString.getBytes(); 90 String valuejson = JSONObject.toJSONString(valuef); 91 byte[] valueb = valuejson.getBytes(Charset.forName("utf-8")); 92 connection.set(keyb, valueb); 93 if (expireInSencods > 0) 94 connection.expire(keyb, expireInSencods); 95 96 return 1L; 97 98 ); 99 100 101 102 @Override 103 public ValueWrapper putIfAbsent(Object key, Object value) 104 // TODO Auto-generated method stub 105 return null; 106 107 108 109 @Override 110 public void evict(Object key) 111 if (logger.isDebugEnabled()) 112 logger.debug("-------緩存刪除------"); 113 114 final String keyf = KEY_PREFIX + key.toString(); 115 redisTemplate.execute(new RedisCallback<Long>() 116 @Override 117 public Long doInRedis(RedisConnection connection) throws DataAccessException 118 return connection.del(keyf.getBytes()); 119 120 121 ); 122 123 124 125 @Override 126 public void clear() 127 if (logger.isDebugEnabled()) 128 logger.debug("-------緩存清理------"); 129 130 redisTemplate.execute(new RedisCallback<String>() 131 @Override 132 public String doInRedis(RedisConnection connection) throws DataAccessException 133 connection.flushDb(); 134 return "ok"; 135 136 ); 137 138 139 /** 140 * @return redisTemplate 141 */ 142 public RedisTemplate<String, Object> getRedisTemplate() 143 return redisTemplate; 144 145 146 /** 147 * @param redisTemplate the redisTemplate to set 148 */ 149 public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) 150 this.redisTemplate = redisTemplate; 151 152 153 /** 154 * @param name the name to set 155 */ 156 public void setName(String name) 157 this.name = name; 158 159 160 /** 161 * @return name 162 */ 163 @Override 164 public String getName() 165 return name; 166 167 168 /** 169 * @return resultType 170 */ 171 public String getResultType() 172 return resultType; 173 174 175 /** 176 * @param resultType the resultType to set 177 */ 178 public void setResultType(String resultType) 179 this.resultType = resultType; 180 181 182 /** 183 * @return expireInSencods 184 */ 185 public long getExpireInSencods() 186 return expireInSencods; 187 188 189 /** 190 * @param expireInSencods the expireInSencods to set 191 */ 192 public void setExpireInSencods(long expireInSencods) 193 this.expireInSencods = expireInSencods; 194 195 196
3、在spring-redis.xml中配置 spring mvc自定义缓存,bean 中的class为我们缓存实现类的包路径,属性均为缓存实现类中的属性。
1 <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"> 2 <property name="caches"> 3 <set> 4 <bean class="xxxx.xxx.xxx.RedisCache"> 5 <property name="redisTemplate" ref="redisTemplate"/> 6 <property name="name" value="wechatapp"/> 7 <property name="expireInSencods" value="7200"/> 8 <property name="resultType" 9 value="xxxx.xx.xxx.xx"/> 10 </bean> 11 </set> 12 </property> 13 </bean>
4、在代码中使用缓存,使用注解 @Cacheable,其中缓存名字cacheNames需要与我们spring redis中配置bean的<property name="name" value="xxx"/>对应起来
@Cacheable(cacheNames = CACHE_NAME,key = "#appid+‘:‘+#secret",unless = "#result == null") @Override public WeChatAppResponseDto getAccessToken(String appid, String secret)
然后执行代码可以发现,在第一次进入的时候,进入方法内部,然后返回结果,再次访问就没有进入方法内部了,可以打断点在缓存获取方法中查看,后面的都直接在缓存中获取了。其实通过引入的相关依赖也可以看出来,该注解功能是利用AOP来实现的。
以上是关于Spring 中使用redis缓存方法记录的主要内容,如果未能解决你的问题,请参考以下文章