引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- springboot starter默认已经引入-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
配置文件
更改application.yml文件如下。这里的type除了用redis,还支持caffeine/jcache/couchbase/ehcache/infinispan/simple(内存缓存) 等类型。需要引入对应依赖。
time-to-live 缓存过期时间ttl,可以用1h,30m等形式表示。
注意spring的cache默认是统一过期时间,没法为每个cache单独设置过期时间,如有这种需求需要自己另行封装
key-prefix 统一key前缀,默认为空
uses-key-prefix redis缓存的key是否使用前缀,默认是true。
需注意,即使上面的key-prefix设为空,在使用@Cacheable等注解时,会将value/cacheName当做key的前缀,实际的key为cacheName + key,需要自己视情况更改配置cache-null-values 是否缓存空值,默认为true。如关闭的话需注意缓存穿透问题
其它各种类型缓存的配置均可在org.springframework.boot.autoconfigure.cache.CacheProperties中找到。
spring:
cache:
type: redis
redis:
time-to-live: 1h #过期时间
use-key-prefix: false #默认为true
# cache-null-values: true # 默认true
最小化实例
在完成以上配置的基础上,在springboot的App启动类上加上注解 @EnableCaching(proxyTargetClass = true)
@EnableCaching(proxyTargetClass = true)
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class,args);
}
}
自定义缓存方法。以用户类User为例,自定义UserRepository来对用户信息进行缓存。
@Cacheable表示该方法使用缓存,value为整个缓存的名称cacheName
key为查询缓存的key,可使用spel表达式,在这里为方法的参数userId。也可以使用keyGenerator来指定生成key的bean
condition为条件表达式。在调用方法前执行,决定是否使用缓存,默认是"",表示结果始终使用缓存
unless为条件表达式,与condition不同的是此表达式是在调用方法之后求值,因此可以引用结果,默认值是"",表示缓存结果永远不会被否决。这里是结果不为空时才缓存(可能存在缓存穿透,此处只是示例)
public class User {
private Long id;
private String name;
//... getter and setter
}
@Component
public class UserRepository {
@Cacheable(value = "userCache",key = "#userId",condition = "#enableCache == true", unless = "#result == null")
public User getUser(Long userId, boolean enableCache) {
//... get userfrom data base
}
}
更改序列化配置
到上一步为止已经可以正常的从缓存获取配置了。但实际上我们没有对缓存进行任何配置,全部使用的默认配置。而Redis Cache默认使用的value序列化方式是JDK序列化,我们一般会改成json序列化,所以这里需要新加一个配置。
@Configuration
public class RedisConfig {
@Bean
public RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) {
CacheProperties.Redis redisProperties = cacheProperties.getRedis();
RedisCacheConfiguration config = RedisCacheConfiguration
.defaultCacheConfig();
config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.json()));
if (redisProperties.getTimeToLive() != null) {
config = config.entryTtl(redisProperties.getTimeToLive());
}
if (redisProperties.getKeyPrefix() != null) {
config = config.prefixCacheNameWith(redisProperties.getKeyPrefix());
}
if (!redisProperties.isCacheNullValues()) {
config = config.disableCachingNullValues();
}
if (!redisProperties.isUseKeyPrefix()) {
config = config.disableKeyPrefix();
}
return config;
}
}