SpringCache
一般不会单独使用,所以配合SpringDataRedis
一起使用,直接上代码
当前基于
SpringBoot 2.4.5
实现
基于已经添加了spring-boot-starter-data-couchbase
还需要添加spring-boot-starter-data-redis
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
仔细观察org.springframework.cache.annotation.EnableCaching
注解的注释,实现功能
负责注册必要的Spring组件,这些组件可以为注释驱动的缓存管理提供支持,例如CacheInterceptor以及基于代理或基于AspectJ的建议将调用@Cacheable方法时,拦截器将进入调用堆栈。如果存在JSR-107 API和Spring的JCache实现,则还将注册用于管理标准缓存注释的必要组件。 这将创建基于代理或基于AspectJ的建议,当调用以CacheResult , CachePut , CacheRemove或CacheRemoveAll注释的方法时,将拦截器编织到调用堆栈中。
必须注册CacheManager类型的Bean ,因为没有合理的默认值可以将该框架用作约定。 尽管<cache:annotation-driven>元素假定一个名为“ cacheManager”的bean,但@EnableCaching按类型搜索一个cache manager bean。 因此,高速缓存管理器bean方法的命名并不重要。
对于那些希望在@EnableCaching和要使用的确切缓存管理器bean之间建立更直接关系的@EnableCaching ,可以实现CachingConfigurer回调接口
这里有个问题,CachingConfigurer
的类型为interface
。即实现所有的方法,查看它的实现CachingConfigurerSupport
类,具有空方法的CachingConfigurer
的实现,允许子类仅覆盖其感兴趣的方法。
查看CachingConfigurer
源码
public class CachingConfigurerSupport implements CachingConfigurer {
/**
* 返回高速缓存管理器bean,以用于注释驱动的高速缓存管理。 默认的CacheResolver将使用此缓存管理器在后台初始化。
* 为了更精细地管理缓存分辨率,请考虑直接设置CacheResolver, 实现必须显式声明@Bean
*/
@Override
@Nullable
public CacheManager cacheManager() {
return null;
}
/**
* 返回CacheResolver bean,用于解析注释驱动的缓存管理的常规缓存。这是指定要使用的CacheManager的替代方法,且
* 功能更强大。如果同时设置了cacheManager()和#cacheResolver() ,则忽略缓存管理器。实现必须显式声明@Bean
*/
@Override
@Nullable
public CacheResolver cacheResolver() {
return null;
}
/**
* 返回密钥生成器Bean,以用于注释驱动的缓存管理。 实现必须显式声明@Bean
*/
@Override
@Nullable
public KeyGenerator keyGenerator() {
return null;
}
/**
* 返回CacheErrorHandler以用于处理与缓存相关的错误。默认情况下,
* 使用org.springframework.cache.interceptor.SimpleCacheErrorHandler ,
* 并且仅将异常抛出回客户端。实现必须显式声明@Bean
*/
@Override
@Nullable
public CacheErrorHandler errorHandler() {
return null;
}
}
现在也做一个CachingConfigurerSupport
的实现
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
/**
* 自定义实现 缓存处理器 将redis修改为默认的缓存处理器
*
* @return
* @see org.springframework.cache.CacheManager
*/
@Bean
@Override
public CacheManager cacheManager() {
return super.cacheManager();
}
/**
* 实现自定义的密钥
* (如果没有自定义实现这个方法会出现什么情况,自定义生成的 redis 键 会像这样 SimpleKey [])
*
* @return
* @see org.springframework.cache.interceptor.KeyGenerator
*/
@Bean
@Override
public KeyGenerator keyGenerator() {
return super.keyGenerator();
}
}
但是这样有个问题,如何才能将缓存管理器交由Reids
管理呢?
有这样的一个类org.springframework.data.redis.cache.RedisCacheManager
,可以看到它的作用是
由Redis缓存支持的org.springframework.cache.CacheManager 。 默认情况下,此高速缓存管理器在首次写入时创建高速缓存。 由于Redis如何表示空数据结构,因此在Redis上看不到空缓存。 可以通过RedisCacheManager.RedisCacheManagerBuilder.withInitialCacheConfigurations(Map)来指定需要与默认配置不同的RedisCacheConfiguration缓存
所以我们需要配置一个redis
的缓存管理器RedisCacheManager
,观察RedisCacheManager
的构造函数
刚开始可以选择使用最简单的一个构造函数,这个构造函数需要两个参数
/**
* 创建新RedisCacheManager使用给定RedisCacheWriter和默认RedisCacheConfiguration 。
*/
public RedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {
this(cacheWriter, defaultCacheConfiguration, true);
}
RedisCacheWriter
提供对用于缓存的Redis命令( SET, SETNX, GET, EXPIRE,… )的低级访问。 RedisCacheWriter可以由多个缓存实现共享,并负责将二进制数据写入Redis或从Redis读取二进制数据。 该实现采用可能设置的潜在缓存锁定标志。RedisCacheConfiguration
提供配置redis
的缓存配置RedisCacheWriter
有两个静态方法,但是都需要RedisConnectionFactory
/**
* 创建没有锁定行为的新RedisCacheWriter
*/
static RedisCacheWriter nonLockingRedisCacheWriter(RedisConnectionFactory connectionFactory) {
Assert.notNull(connectionFactory, "ConnectionFactory must not be null!");
return new DefaultRedisCacheWriter(connectionFactory);
}
/**
* 创建有锁定行为的新RedisCacheWriter
*/
static RedisCacheWriter lockingRedisCacheWriter(RedisConnectionFactory connectionFactory) {
Assert.notNull(connectionFactory, "ConnectionFactory must not be null!");
return new DefaultRedisCacheWriter(connectionFactory, Duration.ofMillis(50));
}
又有一个新的问题RedisConnectionFactory
属于接口,需要如何配置?
RedisConnectionFactory
下有一个实现JedisConnectionFactory
,
JedisConnectionFactory
可以通过Jedis
配置连接工厂
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.6.0</version>
</dependency>
/**
* Redis服务器地址
*/
@Value("${spring.redis.host}")
private String host;
/**
* Redis服务端口
*/
@Value("${spring.redis.port}")
private int port;
/**
* Redis服务密码
*/
@Value("${spring.redis.password}")
private String password;
/**
* Redis服务器地址
*/
@Value("${spring.redis.database}")
private int database;
/**
* redis 连接工厂 必须注册为 Bean
*
* @return
*/
@Bean
public JedisConnectionFactory redisConnectionFactory() {
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(host, port);
config.setDatabase(database);
config.setPassword(password);
return new JedisConnectionFactory(config);
}
RedisCacheConfiguration
提供了默认的配置,即
RedisCacheConfiguration.defaultCacheConfig();
默认配置具有以下特点:
功能 | 描述 |
---|---|
密钥到期 | 永恒 |
缓存空值 | 是的 |
前缀缓存键 | 是的 |
默认前缀 | [实际缓存名称] |
密钥序列化器 | org.springframework.data.redis.serializer.StringRedisSerializer |
值序列化器 | org.springframework.data.redis.serializer.JdkSerializationRedisSerializer |
转换服务 | 具有default缓存密钥转换器的DefaultFormattingConversionService |
现在开始配置 RedisCacheManager
/**
* 自定义实现 缓存处理器 将redis修改为默认的缓存处理器
*
* @return
* @see org.springframework.data.redis.cache.RedisCacheManager
*/
@Bean
public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory) {
return new RedisCacheManager(RedisCacheWriter.lockingRedisCacheWriter(redisConnectionFactory), redisCacheConfiguration());
}
这样就可以实现将SpringCache
缓存交由Redis
去管理。
在这样的过程中,不断的去查询官方的文档的代码,即使看不懂实现的方式,但是这样的过程就是在过度,不能操之过急,一步一步才能继续往下面走。若有不对欢迎指出
喜欢编程的,请关注我的博客https://www.lzmvlog.top/
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。