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 
重写RedisSerializer

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 
View Code

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>
Spring mvc 自定义缓存

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缓存方法记录的主要内容,如果未能解决你的问题,请参考以下文章

SpringSpring缓存机制与Redis的结合

springboot高级特性-redis作为缓存

Redis 缓存

Redis 缓存

redi+keepalive 简单介绍

redis缓存