zoukankan      html  css  js  c++  java
  • 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、启用缓存

     

    <cache:annotation-driven
                cache-manager="cacheManager"/>

    5、在代码中使用缓存,使用注解 @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来实现的。

  • 相关阅读:
    mysql5.7初始化密码报错 ERROR 1820 (HY000): You must reset your password using ALTER USER statement before
    Http2和Http1.X的区别
    gitlab的搭建
    nginx的四层负载均衡和七层负载均衡的区别
    阿里云NAT网关配置
    docker-compose的最简单安装方式
    最快的安装 jdk8的方法
    centos6上搭建gitlab
    大牛讲解信号与系统以及数字信号处理
    【推荐图书】+ 基于Nios II的嵌入式SoPC系统设计与Verilog开发实例+C#入门经典等
  • 原文地址:https://www.cnblogs.com/rolayblog/p/11176270.html
Copyright © 2011-2022 走看看