Spring Cache的基本使用与分析

Spring Cache的基本使用与分析

基本使用

1、所需依赖

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency>

2、配置文件

spring: # redis连接信息 redis: host: 192.168.56.10 port: 6379 cache: # 指定使用的缓存类型 type: redis # 过期时间 redis: time-to-live: 3600000 # 是否开启前缀,默认为true use-key-prefix: true # 键的前缀,如果不配置,默认就是缓存名cacheNames key-prefix: CACHE_ # 是否缓存空置,防止缓存穿透,默认为true cache-null-values: true

3、Spring Cache 提供的注解如下,使用方法参见:,通过这些注解,我们可以方便的操作缓存数据。

@Cacheable:触发缓存写入的操作

@CacheEvict:触发缓存删除的操作

@CachePut:更新缓存,而不会影响方法的执行

@Caching:重新组合要应用于一个方法的多个缓存操作,即对一个方法添加多个缓存操作

@CacheConfig:在类级别共享一些与缓存有关的常见设置

例如,如果需要对返回结果进行缓存,直接在方法上标注 @Cacheable 注解

@Cacheable(cacheNames = "userList") //指定缓存的名字,便于区分不同缓存 public List<User> getUserList() { ... }

4、redis 默认使用 jdk 序列化,需要我们配置序列化机制,自定义一个配置类,否则存入的数据显示乱码

@EnableCaching //开启缓存 @Configuration public class MyCacheConfig { @Bean public RedisCacheConfiguration redisCacheConfiguration(){ RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig(); //指定键和值的序列化机制 config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())); config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())); return config; } }

5、使用以上配置后,虽然乱码的问题解决了,但配置文件又不生效了,比如过期时间等,这是因为在初始化时会判断用户是否自定义了配置文件,如果自定义了,原来的就不会生效,源码如下:

private org.springframework.data.redis.cache.RedisCacheConfiguration determineConfiguration(ClassLoader classLoader) { //如果配置了,就返回自定义的配置 if (this.redisCacheConfiguration != null) { return this.redisCacheConfiguration; } //没配置使用默认的配置 Redis redisProperties = this.cacheProperties.getRedis(); org.springframework.data.redis.cache.RedisCacheConfiguration config = org.springframework.data.redis.cache.RedisCacheConfiguration .defaultCacheConfig(); config = config.serializeValuesWith( SerializationPair.fromSerializer(new JdkSerializationRedisSerializer(classLoader))); 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; }

6、所以,我们也需要手动获取 ttl、prefix 等属性,直接仿照源码就行,将配置类修改为如下:

@EnableCaching //开启缓存 @Configuration @EnableConfigurationProperties(CacheProperties.class) //缓存的所有配置属性都在这个类里 public class MyCacheConfig { @Bean public RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) { //获取默认配置 RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig(); //指定键和值的序列化机制 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; } } 原理分析

在 Spring 中 CacheManager 负责创建管理 Cache,Cache 负责缓存的读写,因此使用 redis 作为缓存对应的就有 RedisCacheManager 和 RedisCache。

打开 RedisCache 源码,我们需要注意这两个方法:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpyzdg.html