redisson-spring-boot-starter:3.25.2
此starter会自动注册RedissonClient Bean
并可通过注册RedissonAutoConfigurationCustomizer Bean实现配置自定义
@Bean
RedissonAutoConfigurationCustomizer jdkCodecCustomizer() {
return configuration->{
// 使用JDK序列化器
configuration.setCodec(new SerializationCodec());
};
}
spring-boot:2.7以上
org.redisson.spring.starter.RedissonAutoConfigurationV2
@AutoConfiguration(before = RedisAutoConfiguration.class)
@ConditionalOnClass({Redisson.class, RedisOperations.class})
@EnableConfigurationProperties({RedissonProperties.class, RedisProperties.class}) // 启用spring.data.redis,spring.redisson配置属性
public class RedissonAutoConfigurationV2 extends RedissonAutoConfiguration {
}
spring-boot:2.6以下
org.redisson.spring.starter.RedissonAutoConfiguration
@Configuration
@ConditionalOnClass({Redisson.class, RedisOperations.class})
// 防止spring-boot:2.7以上版本时跟RedissonAutoConfigurationV2冲突
@ConditionalOnMissingClass("org.springframework.boot.autoconfigure.AutoConfiguration")
@AutoConfigureBefore(RedisAutoConfiguration.class)
@EnableConfigurationProperties({RedissonProperties.class, RedisProperties.class})
public class RedissonAutoConfiguration {
...
// 注册RedissonClient
@Bean(destroyMethod = "shutdown")
@ConditionalOnMissingBean(RedissonClient.class)
public RedissonClient redisson() throws IOException {
Config config;
Method clusterMethod = ReflectionUtils.findMethod(RedisProperties.class, "getCluster");
Method usernameMethod = ReflectionUtils.findMethod(RedisProperties.class, "getUsername");
Method timeoutMethod = ReflectionUtils.findMethod(RedisProperties.class, "getTimeout");
Method connectTimeoutMethod = ReflectionUtils.findMethod(RedisProperties.class, "getConnectTimeout");
Method clientNameMethod = ReflectionUtils.findMethod(RedisProperties.class, "getClientName");
Object timeoutValue = ReflectionUtils.invokeMethod(timeoutMethod, redisProperties);
String prefix = getPrefix();
String username = null;
int database = redisProperties.getDatabase();
String password = redisProperties.getPassword();
boolean isSentinel = false;
boolean isCluster = false;
// 如果存在redis连接详细配置,则从详细配置中获取用户名,密码,哨兵模式标识,集群模式标识
if (hasConnectionDetails()) {
ObjectProvider<RedisConnectionDetails> provider = ctx.getBeanProvider(RedisConnectionDetails.class);
RedisConnectionDetails b = provider.getIfAvailable();
if (b != null) {
password = b.getPassword();
username = b.getUsername();
if (b.getSentinel() != null) {
isSentinel = true;
}
if (b.getCluster() != null) {
isCluster = true;
}
}
}
// 获取redis配置中的超时时间
Integer timeout = null;
if (timeoutValue instanceof Duration) {
timeout = (int) ((Duration) timeoutValue).toMillis();
} else if (timeoutValue != null){
timeout = (Integer)timeoutValue;
}
// 获取redis配置中的连接超时时间
Integer connectTimeout = null;
if (connectTimeoutMethod != null) {
Object connectTimeoutValue = ReflectionUtils.invokeMethod(connectTimeoutMethod, redisProperties);
if (connectTimeoutValue != null) {
connectTimeout = (int) ((Duration) connectTimeoutValue).toMillis();
}
} else {
connectTimeout = timeout;
}
// 获取redis配置中的客户端名称
String clientName = null;
if (clientNameMethod != null) {
clientName = (String) ReflectionUtils.invokeMethod(clientNameMethod, redisProperties);
}
// 获取redis配置中的用户名
if (usernameMethod != null) {
username = (String) ReflectionUtils.invokeMethod(usernameMethod, redisProperties);
}
if (redissonProperties.getConfig() != null) {
// 如果存在redisson配置(在application.yml中以字符串形式配置)
try {
// 尝试解析yml格式配置字符串
config = Config.fromYAML(redissonProperties.getConfig());
} catch (IOException e) {
try {
// 尝试解析json格式配置字符串
config = Config.fromJSON(redissonProperties.getConfig());
} catch (IOException e1) {
e1.addSuppressed(e);
throw new IllegalArgumentException("Can't parse config", e1);
}
}
} else if (redissonProperties.getFile() != null) {
// 如果存在redisson配置文件(yml或json)
try {
InputStream is = getConfigStream();
config = Config.fromYAML(is);
} catch (IOException e) {
// trying next format
try {
InputStream is = getConfigStream();
config = Config.fromJSON(is);
} catch (IOException e1) {
e1.addSuppressed(e);
throw new IllegalArgumentException("Can't parse config", e1);
}
}
} else if (redisProperties.getSentinel() != null || isSentinel) {
// 连接哨兵模式集群
String[] nodes = {};
String sentinelMaster = null;
if (redisProperties.getSentinel() != null) {
Method nodesMethod = ReflectionUtils.findMethod(Sentinel.class, "getNodes");
Object nodesValue = ReflectionUtils.invokeMethod(nodesMethod, redisProperties.getSentinel());
if (nodesValue instanceof String) {
nodes = convert(prefix, Arrays.asList(((String)nodesValue).split(",")));
} else {
nodes = convert(prefix, (List<String>)nodesValue);
}
sentinelMaster = redisProperties.getSentinel().getMaster();
}
String sentinelUsername = null;
String sentinelPassword = null;
if (hasConnectionDetails()) {
ObjectProvider<RedisConnectionDetails> provider = ctx.getBeanProvider(RedisConnectionDetails.class);
RedisConnectionDetails b = provider.getIfAvailable();
if (b != null && b.getSentinel() != null) {
database = b.getSentinel().getDatabase();
sentinelMaster = b.getSentinel().getMaster();
nodes = convertNodes(prefix, (List<Object>) (Object) b.getSentinel().getNodes());
sentinelUsername = b.getSentinel().getUsername();
sentinelPassword = b.getSentinel().getPassword();
}
}
config = new Config();
SentinelServersConfig c = config.useSentinelServers()
.setMasterName(sentinelMaster)
.addSentinelAddress(nodes)
.setSentinelPassword(sentinelPassword)
.setSentinelUsername(sentinelUsername)
.setDatabase(database)
.setUsername(username)
.setPassword(password)
.setClientName(clientName);
if (connectTimeout != null) {
c.setConnectTimeout(connectTimeout);
}
if (connectTimeoutMethod != null && timeout != null) {
c.setTimeout(timeout);
}
initSSL(c);
} else if ((clusterMethod != null && ReflectionUtils.invokeMethod(clusterMethod, redisProperties) != null)
|| isCluster) {
// 连接分片集群
String[] nodes = {};
if (clusterMethod != null && ReflectionUtils.invokeMethod(clusterMethod, redisProperties) != null) {
Object clusterObject = ReflectionUtils.invokeMethod(clusterMethod, redisProperties);
Method nodesMethod = ReflectionUtils.findMethod(clusterObject.getClass(), "getNodes");
List<String> nodesObject = (List) ReflectionUtils.invokeMethod(nodesMethod, clusterObject);
nodes = convert(prefix, nodesObject);
}
if (hasConnectionDetails()) {
ObjectProvider<RedisConnectionDetails> provider = ctx.getBeanProvider(RedisConnectionDetails.class);
RedisConnectionDetails b = provider.getIfAvailable();
if (b != null && b.getCluster() != null) {
nodes = convertNodes(prefix, (List<Object>) (Object) b.getCluster().getNodes());
}
}
config = new Config();
ClusterServersConfig c = config.useClusterServers()
.addNodeAddress(nodes)
.setUsername(username)
.setPassword(password)
.setClientName(clientName);
if (connectTimeout != null) {
c.setConnectTimeout(connectTimeout);
}
if (connectTimeoutMethod != null && timeout != null) {
c.setTimeout(timeout);
}
initSSL(c);
} else {
// 连接单实例
config = new Config();
String singleAddr = prefix + redisProperties.getHost() + ":" + redisProperties.getPort();
if (hasConnectionDetails()) {
ObjectProvider<RedisConnectionDetails> provider = ctx.getBeanProvider(RedisConnectionDetails.class);
RedisConnectionDetails b = provider.getIfAvailable();
if (b != null && b.getStandalone() != null) {
database = b.getStandalone().getDatabase();
singleAddr = prefix + b.getStandalone().getHost() + ":" + b.getStandalone().getPort();
}
}
SingleServerConfig c = config.useSingleServer()
.setAddress(singleAddr)
.setDatabase(database)
.setUsername(username)
.setPassword(password)
.setClientName(clientName);
if (connectTimeout != null) {
c.setConnectTimeout(connectTimeout);
}
if (connectTimeoutMethod != null && timeout != null) {
c.setTimeout(timeout);
}
initSSL(c);
}
// 应用自定义配置bean
if (redissonAutoConfigurationCustomizers != null) {
for (RedissonAutoConfigurationCustomizer customizer : redissonAutoConfigurationCustomizers) {
customizer.customize(config);
}
}
return Redisson.create(config);
}
private void initSSL(BaseConfig<?> config) {
Method getSSLMethod = ReflectionUtils.findMethod(RedisProperties.class, "getSsl");
if (getSSLMethod == null) {
return;
}
RedisProperties.Ssl ssl = redisProperties.getSsl();
if (ssl.getBundle() == null) {
return;
}
ObjectProvider<SslBundles> provider = ctx.getBeanProvider(SslBundles.class);
SslBundles bundles = provider.getIfAvailable();
if (bundles == null) {
return;
}
SslBundle b = bundles.getBundle(ssl.getBundle());
if (b == null) {
return;
}
config.setSslCiphers(b.getOptions().getCiphers());
config.setSslProtocols(b.getOptions().getEnabledProtocols());
config.setSslTrustManagerFactory(b.getManagers().getTrustManagerFactory());
config.setSslKeyManagerFactory(b.getManagers().getKeyManagerFactory());
}
}