赞
踩
上一节我们提到,@Cacheable的默认行为包括:
①可以通过@Cacheable
注解的属性key
自定义。
③可以通过配置文件设置过期时间。
本节将介绍如何修改key、value的序列化机制。
根据SpringBoot的原理,一定有一个类用来封装配置文件中的配置,Spring Cache的这个配置自动装配类是CacheAutoConfiguration
,看这个类的源码,其加载了Redis的配置类RedisCacheConfiguration
,这个类中使用了Spring Cache
的配置创建RedisCacheManger
类,这个类中实现了对Redis的读写操作。
根据源码可以看出,如果容器中有redisCacheConfiguration
对象,就使用容器中的对象,否则就创建一个。
private org.springframework.data.redis.cache.RedisCacheConfiguration determineConfiguration(
CacheProperties cacheProperties,
ObjectProvider<org.springframework.data.redis.cache.RedisCacheConfiguration> redisCacheConfiguration,
ClassLoader classLoader) {
return redisCacheConfiguration.getIfAvailable(() -> createConfiguration(cacheProperties, classLoader));
}
默认是没有向容器中注入redisCacheConfiguration
对象的,会创建一个,但是创建的对象中没有设置key和value的序列化器,会用默认的JDK序列化器。
所以,我们可以向容器中注入一个redisCacheConfiguration
对象,在这个对象中设置JSON序列化器,在创建RedisCacheManger
对象时,就会使用我们注入的对象,redis就会使用我们配置的json序列化。
所以,我们可以自定义一个配置类,向容器中注入redisCacheConfiguration
对象,在创建这个对象时设置序列化方式。
@EnableConfigurationProperties(CacheProperties.class) @Configuration @EnableCaching public class MyCacheConfig { // @Autowired // public CacheProperties cacheProperties; @Bean public RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) { RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig(); // config = config.entryTtl(); config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())); config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())); CacheProperties.Redis redisProperties = cacheProperties.getRedis(); //将配置文件中所有的配置都生效 if (redisProperties.getTimeToLive() != null) { config = config.entryTtl(redisProperties.getTimeToLive()); } if (redisProperties.getKeyPrefix() != null) { config = config.prefixKeysWith(redisProperties.getKeyPrefix()); } if (!redisProperties.isCacheNullValues()) { config = config.disableCachingNullValues(); } if (!redisProperties.isUseKeyPrefix()) { config = config.disableKeyPrefix(); } return config; } }
在这段代码中,创建并向容器中注入了一个RedisCacheConfiguration
对象。
这里需要注意,需要通过@EnableConfigurationProperties
激活CacheProperties
读取和封装配置文件中的配置。
@EnableConfigurationProperties
的作用
@EnableConfigurationProperties
注解告诉Spring框架去查找并激活一个或多个由 @ConfigurationProperties
标记的类,这些类可以用来绑定配置文件中的属性值。@ConfigurationProperties
的类注册为一个配置类,这样就可以直接在Spring容器中注入这些配置类的实例,并且它们会自动绑定到配置文件中的属性。使用 CacheProperties
的两种方式
自动注入 (@Autowired
):
@Autowired
注入 CacheProperties
类的实例,这种方式可以直接在类的字段上使用,不需要额外的方法调用。@Autowired
private CacheProperties cacheProperties;
作为方法参数:
CacheProperties
作为方法参数传递,这种方式通常用于方法内部需要使用配置属性的情况。@Bean
public RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) {
// ...
}
Redis缓存保证最终一致性的失效模式,是在更新数据后将缓存中的数据删除,删除缓存数据可以通过@CacheEvict完成,结合@Caching可以删除多个缓存。
@Caching( evict = {
@CacheEvict(value = {"category"}, key = "'getLevel1Categorys'"),
@CacheEvict(value = {"category"}, key = "'catelogJson'")
}
)
@CacheEvict(value = {"category"}, key = "'getLevel1Categorys'")
对Redis缓存的三个问题:
SpringCache提供相应的解决方案:
Spring.cache.redis.cache-null-values=true
所以,如果实时性要求高、数据一致性要求高,就不能使用Spring Cache,必须自己编写缓存相关的逻辑来实现分布式锁的方案。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。