Spring集成Redisson配置RedissonAutoConfiguration初始化源码解析

时间:2025-03-22 07:59:59

Redisson数据源初始化源码 ,当前版本3.13.6

/**
 * Copyright (c) 2013-2020 Nikita Koksharov
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    /licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ;

import ;
import ;
import ;
import ;
import ;
import ;

import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;

/**
 *
 * @author Nikita Koksharov
 * @author Nikos Kakavas (/nikakis)
 * @author AnJia (/)
 *
 */
@Configuration
@ConditionalOnClass({, })
@AutoConfigureBefore()
@EnableConfigurationProperties({, })
public class RedissonAutoConfiguration {
    //连接协议
    private static final String REDIS_PROTOCOL_PREFIX = "redis://";
    private static final String REDISS_PROTOCOL_PREFIX = "rediss://";

    //自定义加载配置项
    @Autowired(required = false)
    private List<RedissonAutoConfigurationCustomizer> redissonAutoConfigurationCustomizers;

    //redisson配置参数
    //通过前缀进行配置
    @Autowired
    private RedissonProperties redissonProperties;
    
    //Spring-data-Redis配置内容
    @Autowired
    private RedisProperties redisProperties;
    
    //使用配置加载配置文件时使用
    @Autowired
    private ApplicationContext ctx;

    //redisTemplate未初始化时,初始化redisTemplate连接池
    @Bean
    @ConditionalOnMissingBean(name = "redisTemplate")
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
        (redisConnectionFactory);
        return template;
    }
    
    //StringRedisTemplate未初始化时,初始化StringRedisTemplate连接池
    @Bean
    @Bean
    @ConditionalOnMissingBean()
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        StringRedisTemplate template = new StringRedisTemplate();
        (redisConnectionFactory);
        return template;
    }

    //初始化Redisson连接工厂
    @Bean
    @ConditionalOnMissingBean()
    public RedissonConnectionFactory redissonConnectionFactory(RedissonClient redisson) {
        return new RedissonConnectionFactory(redisson);
    }

    //创建redisson连接池
    @Bean(destroyMethod = "shutdown")
    @ConditionalOnMissingBean()
    public RedissonClient redisson() throws IOException {
        Config config = null;
        //获取Spring-data-redis的获取集群方法
        Method clusterMethod = (, "getCluster");
        //获取Spring-data-redis的获取超时时间方法
        Method timeoutMethod = (, "getTimeout");
        //获取Spring-data-redis的中配置的redis连接超时时间
        Object timeoutValue = (timeoutMethod, redisProperties);
        int timeout;
        //没有设置则默认10秒
        if(null == timeoutValue){
            timeout = 10000;
        }else if (!(timeoutValue instanceof Integer)) {
            Method millisMethod = ((), "toMillis");
            timeout = ((Long) (millisMethod, timeoutValue)).intValue();
        } else {
            timeout = (Integer)timeoutValue;
        }
        //读取redis连接池配置
        //根据配置优先级进行配置,只能加载一个配置
        // 配置项
        // 配置文件
        // 哨兵模式
        // 集群模式
        // 单点模式
        if (() != null) {
            try {
                config = (());
            } catch (IOException e) {
                try {
                    config = (());
                } catch (IOException e1) {
                    throw new IllegalArgumentException("Can't parse config", e1);
                }
            }
        } else if (() != null) {
            try {
                InputStream is = getConfigStream();
                config = (is);
            } catch (IOException e) {
                // trying next format
                try {
                    InputStream is = getConfigStream();
                    config = (is);
                } catch (IOException e1) {
                    throw new IllegalArgumentException("Can't parse config", e1);
                }
            }
        } else if (() != null) {
            Method nodesMethod = (, "getNodes");
            Object nodesValue = (nodesMethod, ());

            String[] nodes;
            if (nodesValue instanceof String) {
                nodes = convert((((String)nodesValue).split(",")));
            } else {
                nodes = convert((List<String>)nodesValue);
            }

            config = new Config();
            ()
                .setMasterName(().getMaster())
                .addSentinelAddress(nodes)
                .setDatabase(())
                .setConnectTimeout(timeout)
                .setPassword(());
        } else if (clusterMethod != null && (clusterMethod, redisProperties) != null) {
            Object clusterObject = (clusterMethod, redisProperties);
            Method nodesMethod = ((), "getNodes");
            List<String> nodesObject = (List) (nodesMethod, clusterObject);

            String[] nodes = convert(nodesObject);

            config = new Config();
            ()
                .addNodeAddress(nodes)
                .setConnectTimeout(timeout)
                .setPassword(());
        } else {
            config = new Config();
            String prefix = REDIS_PROTOCOL_PREFIX;
            Method method = (, "isSsl");
            if (method != null && (Boolean)(method, redisProperties)) {
                prefix = REDISS_PROTOCOL_PREFIX;
            }

            ()
                .setAddress(prefix + () + ":" + ())
                .setConnectTimeout(timeout)
                .setDatabase(())
                .setPassword(());
        }
        if (redissonAutoConfigurationCustomizers != null) {
            for (RedissonAutoConfigurationCustomizer customizer : redissonAutoConfigurationCustomizers) {
                (config);
            }
        }
        //根据配置创建连接池
        return (config);
    }

    //Redisson集群协议格式化
    private String[] convert(List<String> nodesObject) {
        List<String> nodes = new ArrayList<String>(());
        for (String node : nodesObject) {
            if (!(REDIS_PROTOCOL_PREFIX) && !(REDISS_PROTOCOL_PREFIX)) {
                (REDIS_PROTOCOL_PREFIX + node);
            } else {
                (node);
            }
        }
        return (new String[()]);
    }
    
    //获取配置文件数据流
    private InputStream getConfigStream() throws IOException {
        Resource resource = (());
        InputStream is = ();
        return is;
    }


}

注意:

  • 配置优先级,如:当和都有配置时,使用集群地址。优先级1>2>3>4>5。
  1. : redisson配置项
  2. : redisson配置文件
  3. : spring-data-redis哨兵模式
  4. : spring-data-redis集群模式
  5. : spring-data-redis单点模式

  • 可复用配置项
  1. : 集群地址
  2. :超时时间
  3. :哨兵名称
  4. :集群节点
  5. :redis库号,单节点用
  6. :redis访问密码,redis中sentinel模式也使用该密码。redisson后续版本可能支持
  7. :是否使用SSL
  8. :单节点地址
  9. :单节点端口

自定义配置

@Configuration
@Slf4j
public class CustomRedissonConfiguration implements RedissonAutoConfigurationCustomizer {

    @Override
    public void customize(Config config) {
        ()
                .setSlaveConnectionMinimumIdleSize(5)
                .setSlaveConnectionPoolSize(20)
                .setMasterConnectionMinimumIdleSize(5)
                .setMasterConnectionPoolSize(20)
                ;
        // 在这里可以修改 Redisson 的配置
        try {
            (());
        } catch (IOException e) {
            ();
        }
    }
}