前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringCache整合SpringDataRedis

SpringCache整合SpringDataRedis

原创
作者头像
是小张啊喂
修改2021-05-17 11:07:45
9990
修改2021-05-17 11:07:45
举报
文章被收录于专栏:软件

SpringCache一般不会单独使用,所以配合SpringDataRedis一起使用,直接上代码

当前基于 SpringBoot 2.4.5 实现

基于已经添加了spring-boot-starter-data-couchbase 还需要添加spring-boot-starter-data-redis依赖

代码语言:javascript
复制
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

仔细观察org.springframework.cache.annotation.EnableCaching注解的注释,实现功能

代码语言:javascript
复制
负责注册必要的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源码

代码语言:javascript
复制
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的实现

代码语言:javascript
复制
@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的构造函数 刚开始可以选择使用最简单的一个构造函数,这个构造函数需要两个参数

代码语言:javascript
复制
/**
 * 创建新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

代码语言:javascript
复制
/**
 * 创建没有锁定行为的新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下有一个实现JedisConnectionFactoryJedisConnectionFactory可以通过Jedis配置连接工厂

代码语言:javascript
复制
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.6.0</version>
</dependency>
代码语言:javascript
复制
 /**
 * 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提供了默认的配置,即

代码语言:javascript
复制
RedisCacheConfiguration.defaultCacheConfig();

默认配置具有以下特点:

功能

描述

密钥到期

永恒

缓存空值

是的

前缀缓存键

是的

默认前缀

[实际缓存名称]

密钥序列化器

org.springframework.data.redis.serializer.StringRedisSerializer

值序列化器

org.springframework.data.redis.serializer.JdkSerializationRedisSerializer

转换服务

具有default缓存密钥转换器的DefaultFormattingConversionService

现在开始配置 RedisCacheManager

代码语言:javascript
复制
/**
 * 自定义实现 缓存处理器 将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 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis®
腾讯云数据库 Redis®(TencentDB for Redis®)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档