码迷,mamicode.com
首页 > 编程语言 > 详细

Spring 中使用redis缓存方法记录

时间:2019-07-12 15:41:29      阅读:140      评论:0      收藏:0      [点我收藏+]

标签:hide   hat   generated   路径   chat   cut   get   ring   code   

背景

  在平时项目中,可能会有某个条件的查询,会多次进到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缓存方法记录

标签:hide   hat   generated   路径   chat   cut   get   ring   code   

原文地址:https://www.cnblogs.com/rolayblog/p/11176270.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!