zoukankan      html  css  js  c++  java
  • SpringBoot2(十)自定义Cache

    自定义Cache十分简单,找到接口,实现它即可,难点是序列化自动转型。

    前面一篇文章已经提到,自定义Cache中 get(Object key, Class<T> aClass) 函数从未被调用,无法用来对接JSON的 parseObject(String json, Class<T> clazz) 函数。

    虽然不理解作者的真实意图,事实已然如此,那就只能尝试解决,编码过程中,需要想办法保存Class的值。

    方法一:

      改写CacheInterceptor接口(位于context核心包下),虽然很简单直接,但是Spring的回答也简单粗暴:“不允许!”项目启动直接报错,强调不允许修改。

    方法二:

      在Key上做文章,KeyGenerator接口需要实现 generate(Object target, Method method, Object... params) 接口,这里能拿到返回值的全类名。

      但是这样做依然不够好,Key值不宜复杂设计,因为Key值用于数据检索,不论基于何种技术实现,Key值越长,检索必定越慢。

    方法三:

      将全类名附加到Value中,这种做法,FastJSON对此作了支持,直接调用即可。需要调用ParserConfig.getGlobalInstance()开启自动转型

      public static void main(String[] args) {
        SysUser user = new SysUser();
        user.setUserNick("aaaaa");
        String str = JSON.toJSONString(user, FastJsonUtils.serializeConfig, SerializerFeature.WriteClassName);
    
        System.out.println(str);
    
        ParserConfig.getGlobalInstance().addAccept("cn.seaboot.admin.bean.");
        System.out.println(JSON.parse(str).getClass());
      }

    自定义Cache简单的实现:

    CacheConfig

    import org.springframework.cache.CacheManager;
    import org.springframework.cache.annotation.CachingConfigurerSupport;
    import org.springframework.context.annotation.Bean;
    
    /**
     * @author Mr.css
     * @date 2019/12/23
     */
    @Configuration
    public class CacheConfig extends CachingConfigurerSupport {
    
      @Bean
      @Override
      public CacheManager cacheManager() {
        return new RedisCacheManager();
      }
    }

     CacheManager

    import org.springframework.cache.Cache;
    import org.springframework.cache.support.AbstractCacheManager;
    
    import java.util.ArrayList;
    import java.util.Collection;
    
    public class RedisCacheManager extends AbstractCacheManager {
    
      @Override
      protected Collection<? extends Cache> loadCaches() {
        return new ArrayList<>();
      }
    
      @Override
      protected Cache getMissingCache(String name) {
        return new RedisCache();
      }
    }

     Cache 

    import cn.seaboot.admin.consts.SystemConst;
    import cn.seaboot.common.core.Converter;
    import org.springframework.cache.Cache;
    import org.springframework.cache.support.SimpleValueWrapper;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.concurrent.Callable;
    
    /**
     *
     */
    public class RedisCache implements Cache {
    
      Map<Object, Object> map = new HashMap<>();
    
      /**
       * 简单直白,就是获取Cache的名字
       */
      @Override
      public String getName() {
        return SystemConst.CACHE_DEF;
      }
    
      /**
       * 获取底层的缓存实现对象
       */
      @Override
      public Object getNativeCache() {
        return SystemConst.CACHE_DEF;
      }
    
      /**
       * 根据键获取值,把值包装在ValueWrapper里面,如果有必要可以附加额外信息
       */
      @Override
      public ValueWrapper get(Object key) {
        System.out.println("ValueWrapper");
        return map.containsKey(key)?new SimpleValueWrapper(map.get(key)):null;
      }
    
      /**
       *
       */
      @Override
      public <T> T get(Object key, Class<T> aClass) {
        try {
          System.out.println("get(Object o, Class<T> aClass)");
          return map.containsKey(key)?Converter.convert(map.get(key), aClass):null;
        } catch (Exception e) {
          e.printStackTrace();
        }
        return null;
      }
    
      /**
       * 与sync属性有关
       */
      @Override
      public <T> T get(Object key, Callable<T> valueLoader) {
        try {
          System.out.println("get");
          return valueLoader.call();
        } catch (Exception e) {
          e.printStackTrace();
        }
        return null;
      }
    
      /**
       * 存放键值对
       */
      @Override
      public void put(Object key, Object value) {
        System.out.println("put(Object key, Object value)");
        map.put(key, value);
      }
    
      /**
       * 如果键对应的值不存在,则添加键值对
       */
      @Override
      public ValueWrapper putIfAbsent(Object key, Object value) {
        System.out.println("putIfAbsent");
        map.put(key, value);
        return new SimpleValueWrapper(value);
      }
    
      /**
       * 移除键对应键值对
       */
      @Override
      public void evict(Object key) {
        System.out.println("evict");
        map.remove(key);
      }
    
      /**
       * 清空缓存
       */
      @Override
      public void clear() {
        System.out.println("clear");
        map.clear();
      }
    }

     

  • 相关阅读:
    OnContextMenu事件
    一个不错的js制作的右键菜单
    用JS访问iframe中的元素
    Java中static、final用法小结
    Android系统层次结构及分析
    final 与static final修饰变量区别
    Jquery取得iframe中元素的几种方法Javascript Jquery获取Iframe的元素、内容或者ID,反之也行!
    js+css实现页面右键菜单
    编码和字符集的关系
    关于互联网开放的一点看法
  • 原文地址:https://www.cnblogs.com/chenss15060100790/p/12130385.html
Copyright © 2011-2022 走看看