Spring @Cacheable 注解 小知识点儿

1.反序列化复杂对象应该注意的事情

  使用 JSON.parseObject(jsonString,MyModel.class); 反序列化复杂对象时,包含的属性类必须有无参的构造方法,否则容易出现丢失属性的的问题;

2.使用Redis作为缓存时 可以自定义序列化方法

  好处:可以直接查看缓存内容,不容易出现 ClassCastException 异常

 自定义序列化实现类如下:

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import java.nio.charset.Charset;

/**
 * 说明:自定义redis序列化方式 防止 @Cacheabl 注解不能用(会报类转换异常)
 */
public class FastJsonRedisSerializer implements RedisSerializer {

     public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

     private Class clazz;

     static {
        //使用Redis 配置替换fastjson 反序列化报错 com.alibaba.fastjson.JSONException: autoType is not support
        //加入白名单就好了
        ParserConfig.getGlobalInstance().addAccept("com.xxx.xxx");
     }

     public FastJsonRedisSerializer(Class clazz){
         super();
         this.clazz = clazz;
     }

     @Override
     public byte[] serialize(T t) throws SerializationException{
         if(t ==null){
             return new byte[0];
         }
         return JSON.toJSONString(t,SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
     }

     @Override
     public T deserialize(byte[] bytes)throws SerializationException{
         if(bytes ==null|| bytes.length <=0){
             return null;
         }
         String str = new String(bytes, DEFAULT_CHARSET);
         return JSON.parseObject(str, clazz);
     }
 }

使用时 给 RedisCacheConfiguration 设置序列化方式即可(多数在 @Bean 方法体内添加修改即可)

RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
//自定义序列化方式(默认的序列化方式无法查看redis中的Val 经常会出现类转换异常)
config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new FastJsonRedisSerializer<>(Object.class)));

3.使用时正常使用缓存即可

@Cacheable(value = {"cache_1min"}, key = "'summary:' + #query.code + ':' + #query.code + ':' + #query.dimension ")
public summary query(SearchBase query) 

4.一个比较简单的缓存Key自动生成策略

   /**
     * 缓存 @Cacheable  key 自动生成策略
     * @return
     */
    @Bean
    public KeyGenerator customKeyGenerator() {
        return (target, method, params) -> {
            StringBuilder sb = new StringBuilder();
            sb.append(target.getClass().getSimpleName()).append(":");
            sb.append(method.getName()).append(":");
            if(null!=params){
                if(params instanceof Object[]){
                    sb.append(StringUtils.arrayToCommaDelimitedString(params));
                }else{
                    sb.append(StringUtils.arrayToCommaDelimitedString(new Object[]{params}));
                }
            }else{
                sb.append("no_params");
            }
            return sb.toString();
        };
    }

//使用方式  @Cacheable(value = {"cache_value"}, keyGenerator = "customKeyGenerator")

 

你可能感兴趣的:(缓存相关,redis,spring,cache)