文章目录
主要流程
- 配置redis依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.3.5.RELEASE</version>
</dependency>
- 对应jar包导入后,Spring Boot根据factories.properties中的自动配置类RedisAutoConfiguration自动完成对redis的配置
源码分析
RedisAutoConfiguration
加载配置文件RedisProperties,通过LettuceConnectionConfiguration配置类导入redis的java驱动包,实现redis自动配置
@Configuration(proxyBeanMethods = false)
// 在spring-data-redis jar包存在时加载
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
@Bean
// 在没有配置redisTemplate时默认创建
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
RedisTemplate
屏蔽了redis客户端的连接流程,提供redis的常用命令操作
关系图
实现InitializingBean在bean属性填充完成后初始序列化器
RedisOperations接口封装了redis常用命令
RedisAccessor提供get、set方法设置RedisConnectionFactory
命令执行流程
以keys命令举例,rawKey方法调用了key序列化器来处理pattern,redisTemplate命令实际是调用其execute方法,将RedisConnection的keys方法封装为RedisCallback来处理
public Set<K> keys(K pattern) {
byte[] rawKey = rawKey(pattern);
Set<byte[]> rawKeys = execute(connection -> connection.keys(rawKey), true);
return keySerializer != null ? SerializationUtils.deserialize(rawKeys, keySerializer) : (Set<K>) rawKeys;
}
public <T> T execute(RedisCallback<T> action, boolean exposeConnection, boolean pipeline) {
// 获得RedisConnectionFactory
RedisConnectionFactory factory = getRequiredConnectionFactory();
RedisConnection conn = null;
try {
// 根据RedisConnectionFactory 获得 RedisConnection
if (enableTransactionSupport) {
// 仅在可能发生事务同步的情况下绑定资源
conn = RedisConnectionUtils.bindConnection(factory, enableTransactionSupport);
} else {
conn = RedisConnectionUtils.getConnection(factory);
}
boolean existingConnection = TransactionSynchronizationManager.hasResource(factory);
// 拓展,子类实现
RedisConnection connToUse = preProcessConnection(conn, existingConnection);
boolean pipelineStatus = connToUse.isPipelined();
if (pipeline && !pipelineStatus) {
connToUse.openPipeline();
}
// 如果exposeConnection为FALSE则返回当前conn的代理对象
RedisConnection connToExpose = (exposeConnection ? connToUse : createRedisConnectionProxy(connToUse));
// 调用RedisCallback中方法获得返回结果
T result = action.doInRedis(connToExpose);
// close pipeline
if (pipeline && !pipelineStatus) {
connToUse.closePipeline();
}
// 拓展,子类实现
return postProcessResult(result, connToUse, existingConnection);
} finally {
RedisConnectionUtils.releaseConnection(conn, factory, enableTransactionSupport);
}
}
LettuceConnectionConfiguration
Lettuce是一个高性能基于Java编写的Redis驱动框架,提供了十分丰富易用的API
@Configuration(proxyBeanMethods = false)
// 当io.lettuce.core jar包导入才加载
@ConditionalOnClass(RedisClient.class)
class LettuceConnectionConfiguration extends RedisConnectionConfiguration {
// 默认构造方法,参数分别为redis参数、redis哨兵配置、redis集群配置
LettuceConnectionConfiguration(RedisProperties properties,
ObjectProvider<RedisSentinelConfiguration> sentinelConfigurationProvider,
ObjectProvider<RedisClusterConfiguration> clusterConfigurationProvider) {
super(properties, sentinelConfigurationProvider, clusterConfigurationProvider);
}
@Bean(destroyMethod = "shutdown")
@ConditionalOnMissingBean(ClientResources.class)
DefaultClientResources lettuceClientResources() {
return DefaultClientResources.create();
}
// 创建的LettuceConnectionFactory用来在RedisAutoConfiguration类中构建redisTemplate
@Bean
@ConditionalOnMissingBean(RedisConnectionFactory.class)
LettuceConnectionFactory redisConnectionFactory(
ObjectProvider<LettuceClientConfigurationBuilderCustomizer> builderCustomizers,
ClientResources clientResources) throws UnknownHostException {
// 获得客户端配置,是否ssl、超时等
LettuceClientConfiguration clientConfig = getLettuceClientConfiguration(builderCustomizers, clientResources,
getProperties().getLettuce().getPool());
// 根据配置创建RedisConnectionFactory
return createLettuceConnectionFactory(clientConfig);
}
}
RedisConnectionFactory
创建连接的工厂,通过配置文件创建redis客户端获得连接。
实现InitializingBean接口在初始化bean时根据配置信息创建RedisClient,然后根据client创建连接提供器
实现DisposableBean接口在销毁bean时关闭redis客户端