先看spring-boot-redis的grade构建文件
-
plugins {
-
id
"org.springframework.boot.starter"
-
}
-
-
description =
"Starter for using Redis key-value data store with Spring Data Redis and the Lettuce client"
-
-
dependencies {
-
api(project(
":spring-boot-project:spring-boot-starters:spring-boot-starter"))
-
api(
"org.springframework.data:spring-data-redis")
-
api(
"io.lettuce:lettuce-core")
-
}
他依赖了spring-data-redis,等下就看看这部分内容
先来看看spring-boot-redis的autoConfig内容。
spring-boot-autoconfig并没有为redis单独建个目录,redis的内容放在cache目录下。
其实,autoconfig所有扫描文件都会被扫描到并根据各种@Conditional条件,来判断该配置是否生效并纳入容器中。
cache目录的配置类入口,我认为是CacheAutoConfiguration
-
@AutoConfiguration(after = { CouchbaseDataAutoConfiguration.class, HazelcastAutoConfiguration.class,
-
HibernateJpaAutoConfiguration.class, RedisAutoConfiguration.class })
-
@ConditionalOnClass(CacheManager.class)
-
@ConditionalOnBean(CacheAspectSupport.class)
-
@ConditionalOnMissingBean(value = CacheManager.class, name = "cacheResolver")
-
@EnableConfigurationProperties(CacheProperties.class)
-
@Import({ CacheConfigurationImportSelector.class, CacheManagerEntityManagerFactoryDependsOnPostProcessor.class })
-
public
class
CacheAutoConfiguration {
-
}
我们先看redis的配置,在CacheAutoConfiguration里面声明RedisAutoConfiguration已经先实例化好了。
-
@AutoConfiguration
-
@ConditionalOnClass(RedisOperations.class)
-
@EnableConfigurationProperties(RedisProperties.class)
-
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
-
public
class
RedisAutoConfiguration {
-
-
@Bean
-
@ConditionalOnMissingBean(name = "redisTemplate")
-
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
-
public RedisTemplate<Object, Object>
redisTemplate
(RedisConnectionFactory redisConnectionFactory) {
-
RedisTemplate<Object, Object> template =
new
RedisTemplate<>();
-
template.setConnectionFactory(redisConnectionFactory);
-
return template;
-
}
-
-
@Bean
-
@ConditionalOnMissingBean
-
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
-
public StringRedisTemplate
stringRedisTemplate
(RedisConnectionFactory redisConnectionFactory) {
-
return
new
StringRedisTemplate(redisConnectionFactory);
-
}
-
-
}
通过RedisProperties引入了redis的配置,通过@Import JedisConnectionConfiguration的形式引进了RedisConnetionFactory,并将RedisConnectionFactor传给了Template
再看看JedisConnectionConfiguration,因为它继承了RedisConnectionConfiguration,所以我们先看看RedisConnectionConfiguration有什么逻辑
-
package org.springframework.boot.autoconfigure.data.redis;
-
-
import java.net.URI;
-
import java.net.URISyntaxException;
-
import java.util.ArrayList;
-
import java.util.List;
-
-
import org.springframework.beans.factory.ObjectProvider;
-
import org.springframework.boot.autoconfigure.data.redis.RedisProperties.Pool;
-
import org.springframework.data.redis.connection.RedisClusterConfiguration;
-
import org.springframework.data.redis.connection.RedisNode;
-
import org.springframework.data.redis.connection.RedisPassword;
-
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
-
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
-
import org.springframework.util.ClassUtils;
-
import org.springframework.util.StringUtils;
-
-
/**
-
* Base Redis connection configuration.
-
*
-
* @author Mark Paluch
-
* @author Stephane Nicoll
-
* @author Alen Turkovic
-
* @author Scott Frederick
-
* @author Eddú Meléndez
-
*/
-
abstract
class
RedisConnectionConfiguration {
-
-
private
static
final
boolean
COMMONS_POOL2_AVAILABLE
= ClassUtils.isPresent(
"org.apache.commons.pool2.ObjectPool",
-
RedisConnectionConfiguration.class.getClassLoader());
-
-
private
final RedisProperties properties;
-
-
private
final RedisStandaloneConfiguration standaloneConfiguration;
-
-
private
final RedisSentinelConfiguration sentinelConfiguration;
-
-
private
final RedisClusterConfiguration clusterConfiguration;
-
-
protected
RedisConnectionConfiguration
(RedisProperties properties,
-
ObjectProvider<RedisStandaloneConfiguration> standaloneConfigurationProvider,
-
ObjectProvider<RedisSentinelConfiguration> sentinelConfigurationProvider,
-
ObjectProvider<RedisClusterConfiguration> clusterConfigurationProvider) {
-
this.properties = properties;
-
this.standaloneConfiguration = standaloneConfigurationProvider.getIfAvailable();
-
this.sentinelConfiguration = sentinelConfigurationProvider.getIfAvailable();
-
this.clusterConfiguration = clusterConfigurationProvider.getIfAvailable();
-
}
-
-
protected
final RedisStandaloneConfiguration
getStandaloneConfig
() {
-
if (
this.standaloneConfiguration !=
null) {
-
return
this.standaloneConfiguration;
-
}
-
RedisStandaloneConfiguration
config
=
new
RedisStandaloneConfiguration();
-
if (StringUtils.hasText(
this.properties.getUrl())) {
-
ConnectionInfo
connectionInfo
= parseUrl(
this.properties.getUrl());
-
config.setHostName(connectionInfo.getHostName());
-
config.setPort(connectionInfo.getPort());
-
config.setUsername(connectionInfo.getUsername());
-
config.setPassword(RedisPassword.of(connectionInfo.getPassword()));
-
}
-
else {
-
config.setHostName(
this.properties.getHost());
-
config.setPort(
this.properties.getPort());
-
config.setUsername(
this.properties.getUsername());
-
config.setPassword(RedisPassword.of(
this.properties.getPassword()));
-
}
-
config.setDatabase(
this.properties.getDatabase());
-
return config;
-
}
-
-
protected
final RedisSentinelConfiguration
getSentinelConfig
() {
-
if (
this.sentinelConfiguration !=
null) {
-
return
this.sentinelConfiguration;
-
}
-
RedisProperties.
Sentinel
sentinelProperties
=
this.properties.getSentinel();
-
if (sentinelProperties !=
null) {
-
RedisSentinelConfiguration
config
=
new
RedisSentinelConfiguration();
-
config.master(sentinelProperties.getMaster());
-
config.setSentinels(createSentinels(sentinelProperties));
-
config.setUsername(
this.properties.getUsername());
-
if (
this.properties.getPassword() !=
null) {
-
config.setPassword(RedisPassword.of(
this.properties.getPassword()));
-
}
-
config.setSentinelUsername(sentinelProperties.getUsername());
-
if (sentinelProperties.getPassword() !=
null) {
-
config.setSentinelPassword(RedisPassword.of(sentinelProperties.getPassword()));
-
}
-
config.setDatabase(
this.properties.getDatabase());
-
return config;
-
}
-
return
null;
-
}
-
-
/**
-
* Create a {@link RedisClusterConfiguration} if necessary.
-
* @return {@literal null} if no cluster settings are set.
-
*/
-
protected
final RedisClusterConfiguration
getClusterConfiguration
() {
-
if (
this.clusterConfiguration !=
null) {
-
return
this.clusterConfiguration;
-
}
-
if (
this.properties.getCluster() ==
null) {
-
return
null;
-
}
-
RedisProperties.
Cluster
clusterProperties
=
this.properties.getCluster();
-
RedisClusterConfiguration
config
=
new
RedisClusterConfiguration(clusterProperties.getNodes());
-
if (clusterProperties.getMaxRedirects() !=
null) {
-
config.setMaxRedirects(clusterProperties.getMaxRedirects());
-
}
-
config.setUsername(
this.properties.getUsername());
-
if (
this.properties.getPassword() !=
null) {
-
config.setPassword(RedisPassword.of(
this.properties.getPassword()));
-
}
-
return config;
-
}
-
-
protected
final RedisProperties
getProperties
() {
-
return
this.properties;
-
}
-
-
protected
boolean
isPoolEnabled
(Pool pool) {
-
Boolean
enabled
= pool.getEnabled();
-
return (enabled !=
null) ? enabled : COMMONS_POOL2_AVAILABLE;
-
}
-
-
private List<RedisNode>
createSentinels
(RedisProperties.Sentinel sentinel) {
-
List<RedisNode> nodes =
new
ArrayList<>();
-
for (String node : sentinel.getNodes()) {
-
try {
-
nodes.add(RedisNode.fromString(node));
-
}
-
catch (RuntimeException ex) {
-
throw
new
IllegalStateException(
"Invalid redis sentinel property '" + node +
"'", ex);
-
}
-
}
-
return nodes;
-
}
-
-
protected ConnectionInfo
parseUrl
(String url) {
-
try {
-
URI
uri
=
new
URI(url);
-
String
scheme
= uri.getScheme();
-
if (!
"redis".equals(scheme) && !
"rediss".equals(scheme)) {
-
throw
new
RedisUrlSyntaxException(url);
-
}
-
boolean
useSsl
= (
"rediss".equals(scheme));
-
String
username
=
null;
-
String
password
=
null;
-
if (uri.getUserInfo() !=
null) {
-
String
candidate
= uri.getUserInfo();
-
int
index
= candidate.indexOf(
':');
-
if (index >=
0) {
-
username = candidate.substring(
0, index);
-
password = candidate.substring(index +
1);
-
}
-
else {
-
password = candidate;
-
}
-
}
-
return
new
ConnectionInfo(uri, useSsl, username, password);
-
}
-
catch (URISyntaxException ex) {
-
throw
new
RedisUrlSyntaxException(url, ex);
-
}
-
}
-
-
static
class
ConnectionInfo {
-
-
private
final URI uri;
-
-
private
final
boolean useSsl;
-
-
private
final String username;
-
-
private
final String password;
-
-
ConnectionInfo(URI uri,
boolean useSsl, String username, String password) {
-
this.uri = uri;
-
this.useSsl = useSsl;
-
this.username = username;
-
this.password = password;
-
}
-
-
boolean
isUseSsl
() {
-
return
this.useSsl;
-
}
-
-
String
getHostName
() {
-
return
this.uri.getHost();
-
}
-
-
int
getPort
() {
-
return
this.uri.getPort();
-
}
-
-
String
getUsername
() {
-
return
this.username;
-
}
-
-
String
getPassword
() {
-
return
this.password;
-
}
-
-
}
-
-
}
它的逻辑,首先它定义了一个parse方法,对URL进行解析,获取到uri,username和password,并生成了一个Connection对象
然后定义了getStandaloneConfig方法,这个方法主要是完成RedisStandaloneConfig的初始化并返回 ,先判断properties中的url配置是否为空,不为空则调用parse()方法完成RedisStandaloneConfiguration的初始化,为空则用Properties的username等属性完成初始化
再来看JedisConnectionConfiguration类
它主要用createJedisConnectionFactory方法完成JedisConnectionFactory的创建
-
private JedisConnectionFactory
createJedisConnectionFactory
(
-
ObjectProvider<JedisClientConfigurationBuilderCustomizer> builderCustomizers) {
-
JedisClientConfiguration
clientConfiguration
= getJedisClientConfiguration(builderCustomizers);
-
if (getSentinelConfig() !=
null) {
-
return
new
JedisConnectionFactory(getSentinelConfig(), clientConfiguration);
-
}
-
if (getClusterConfiguration() !=
null) {
-
return
new
JedisConnectionFactory(getClusterConfiguration(), clientConfiguration);
-
}
-
return
new
JedisConnectionFactory(getStandaloneConfig(), clientConfiguration);
-
}
可以看到它调用了getStandaloneConfig()方法,做为其中一个参数,还调用getJedisClientConfiguration()方法
-
private JedisClientConfiguration
getJedisClientConfiguration
(
-
ObjectProvider<JedisClientConfigurationBuilderCustomizer> builderCustomizers) {
-
JedisClientConfigurationBuilder
builder
= applyProperties(JedisClientConfiguration.builder());
-
RedisProperties.
Pool
pool
= getProperties().getJedis().getPool();
-
if (isPoolEnabled(pool)) {
-
applyPooling(pool, builder);
-
}
-
if (StringUtils.hasText(getProperties().getUrl())) {
-
customizeConfigurationFromUrl(builder);
-
}
-
builderCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
-
return builder.build();
-
}
在applyPooling方法里面,用了RedisProperties.Pool pool的属性完成JedisPoolConfig的初始化
-
private
void
applyPooling
(RedisProperties.Pool pool,
-
JedisClientConfiguration.JedisClientConfigurationBuilder builder) {
-
builder.usePooling().poolConfig(jedisPoolConfig(pool));
-
}
-
-
private JedisPoolConfig
jedisPoolConfig
(RedisProperties.Pool pool) {
-
JedisPoolConfig
config
=
new
JedisPoolConfig();
-
config.setMaxTotal(pool.getMaxActive());
-
config.setMaxIdle(pool.getMaxIdle());
-
config.setMinIdle(pool.getMinIdle());
-
if (pool.getTimeBetweenEvictionRuns() !=
null) {
-
config.setTimeBetweenEvictionRuns(pool.getTimeBetweenEvictionRuns());
-
}
-
if (pool.getMaxWait() !=
null) {
-
config.setMaxWait(pool.getMaxWait());
-
}
-
return config;
-
}
转载:https://blog.csdn.net/AAA821/article/details/128309213