1. 三种不同的Redis连接方式:标准、Sentinel、Cluster。
2. 二种不同的Redis客户端连接器:Jedis、Lettuce。(互斥的只使用一种)
3. RedisTemplate 封装的Redis的操作。
一. 配置:
1. 开关:prefix = "spring.redis" 前缀
2. 属性配置:(与RedisProperties.class属性相对应)
spring: redis: database: 0 host: 47.94.10.65 port: 6379 password: 120118 timeout: 1000 lettuce: pool: max-active: 8 max-wait: -1 max-idle: 8 min-idle: 0
/**
* 1.三种不同的连接方式:标准、Sentinel、Cluster。
* 2.三种不同的连接客户端连接器:Jedis、Lettuce。(互斥的只使用一种)
* 生成 RedisConnectionFactory Bean 优先使用Lettuce方式。二个是互斥的
* class RedisAutoConfiguration 里的配置决定使用哪种连接器
*@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class})
*
*/
@ConfigurationProperties(prefix = "spring.redis")
public class RedisProperties {
/**
* Database index used by the connection factory.
*/
private int database = 0;
/**
* Connection URL. Overrides host, port, and password. User is ignored. Example:
* redis://user:[email protected]:6379
*/
private String url;
/**
* Redis server host.
*/
private String host = "localhost";
/**
* Login password of the redis server.
*/
private String password;
/**
* Redis server port.
*/
private int port = 6379;
/**
* Whether to enable SSL support.
*/
private boolean ssl;
/**
* Connection timeout.
*/
private Duration timeout;
private Sentinel sentinel;
private Cluster cluster;
/**
* Jedis client properties.
*/
private final Jedis jedis = new Jedis();
/**
* lettuce client properties.
*/
private final Lettuce lettuce = new Lettuce();
}
二、启动配置入口:(RedisAutoConfiguration.class)
1. 配置启动:
@Configuration
@ConditionalOnClass(RedisOperations.class)
//生成RedisProperties Bean
@EnableConfigurationProperties(RedisProperties.class)
//生成 RedisConnectionFactory Bean 优先使用Lettuce方式。二个是互斥的
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
//生成RedisTemplate默认使用的 jdkSerial序列化。
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate
2. 连接器配置、筛选:
一、JedisConnectionConfiguration配置
/**
* 1. 依赖于Jedis.class(redis:client:jedis包)不引入reids.client客户端不生效
*
*/
@Configuration
@ConditionalOnClass({ GenericObjectPool.class, JedisConnection.class, Jedis.class })
class JedisConnectionConfiguration extends RedisConnectionConfiguration {
/**
* 保证互斥只有一个RedisConnectionFactory
*/
@Bean
@ConditionalOnMissingBean(RedisConnectionFactory.class)
public JedisConnectionFactory redisConnectionFactory() throws UnknownHostException {
return createJedisConnectionFactory();
}
}
二、LettuceConnectionConfiguration配置
/**
* 1. 依赖于RedisClient.class(io.lettuce:lettuce-core包)不引入客户端不生效
*
*/
@Configuration
@ConditionalOnClass(RedisClient.class)
class LettuceConnectionConfiguration extends RedisConnectionConfiguration {
private final RedisProperties properties;
/**
* 保证互斥只有一个RedisConnectionFactory
*/
@Bean
@ConditionalOnMissingBean(RedisConnectionFactory.class)
public LettuceConnectionFactory redisConnectionFactory(
ClientResources clientResources) throws UnknownHostException {
}
3. 连接方式配置、选择:
(1)连接方式配置:
abstract class RedisConnectionConfiguration {
private final RedisProperties properties;
private final RedisSentinelConfiguration sentinelConfiguration;
private final RedisClusterConfiguration clusterConfiguration;
protected RedisConnectionConfiguration(RedisProperties properties,
ObjectProvider sentinelConfigurationProvider,
ObjectProvider clusterConfigurationProvider) {
this.properties = properties;
this.sentinelConfiguration = sentinelConfigurationProvider.getIfAvailable();
this.clusterConfiguration = clusterConfigurationProvider.getIfAvailable();
}
/**
* 1.标准连接方式的配置
*
*/
protected final RedisStandaloneConfiguration getStandaloneConfig() {
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.setPassword(RedisPassword.of(connectionInfo.getPassword()));
}
else {
config.setHostName(this.properties.getHost());
config.setPort(this.properties.getPort());
config.setPassword(RedisPassword.of(this.properties.getPassword()));
}
config.setDatabase(this.properties.getDatabase());
return config;
}
/**
* 2.Sentinel连接方式的配置
*
*/
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));
if (this.properties.getPassword() != null) {
config.setPassword(RedisPassword.of(this.properties.getPassword()));
}
config.setDatabase(this.properties.getDatabase());
return config;
}
return null;
}
/**
* 3.Cluster连接方式的配置
*
*/
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());
}
if (this.properties.getPassword() != null) {
config.setPassword(RedisPassword.of(this.properties.getPassword()));
}
return config;
}
}
(2)选择连接方式:
根据不同的连接方式的配置:优先生成 Sentinel--->Cluster-->Standalone
@Configuration
@ConditionalOnClass(RedisClient.class)
class LettuceConnectionConfiguration extends RedisConnectionConfiguration {
private final RedisProperties properties;
@Bean
@ConditionalOnMissingBean(RedisConnectionFactory.class)
public LettuceConnectionFactory redisConnectionFactory(
ClientResources clientResources) throws UnknownHostException {
LettuceClientConfiguration clientConfig = getLettuceClientConfiguration(
clientResources, this.properties.getLettuce().getPool());
return createLettuceConnectionFactory(clientConfig);
}
/**
* 根据不同的连接方式的配置:优先生成 Sentinel--->Cluster-->Standalone
*/
private LettuceConnectionFactory createLettuceConnectionFactory(
LettuceClientConfiguration clientConfiguration) {
if (getSentinelConfig() != null) {
return new LettuceConnectionFactory(getSentinelConfig(), clientConfiguration);
}
if (getClusterConfiguration() != null) {
return new LettuceConnectionFactory(getClusterConfiguration(),
clientConfiguration);
}
return new LettuceConnectionFactory(getStandaloneConfig(), clientConfiguration);
}
}
四、使用:
直接使用stringRedisTemplate、redisTemplate 里的api操作Redis.