Redisson自动配置RedissonAutoConfiguration源码

        为何研究:公司项目先配置了redis集群,但是在某些地方需要使用分布式锁。后面才加的redisson。因为需求只需要改redisson的某些配置,所以网上常用的在yaml中配置的方法就不怎么好用了。如果想配置某些字段,还需要把集群地址再配置一遍,非常不人性化。在网上搜索良久,未发现符合我需求的。正想放弃之际,突然灵光一闪。我们什么都不配置的时候redisson是如何默认的呢。于是一路溯源,找到了RedissonAutoConfiguration(见名知意,自动配置)。

 @Bean(
        destroyMethod = "shutdown"
    )
    @ConditionalOnMissingBean({RedissonClient.class})
    public RedissonClient redisson() throws IOException {
        Config config = null;
        Method clusterMethod = ReflectionUtils.findMethod(RedisProperties.class, "getCluster");
        Method timeoutMethod = ReflectionUtils.findMethod(RedisProperties.class, "getTimeout");
        Object timeoutValue = ReflectionUtils.invokeMethod(timeoutMethod, this.redisProperties);
        int timeout;
        Method nodesMethod;
        if (null == timeoutValue) {
            timeout = 10000;
        } else if (!(timeoutValue instanceof Integer)) {
            nodesMethod = ReflectionUtils.findMethod(timeoutValue.getClass(), "toMillis");
            timeout = ((Long)ReflectionUtils.invokeMethod(nodesMethod, timeoutValue)).intValue();
        } else {
            timeout = (Integer)timeoutValue;
        }
        //1、判断spring.redis.redisson是否有config配置
        if (this.redissonProperties.getConfig() != null) {
            try {
                config = Config.fromYAML(this.redissonProperties.getConfig());
            } catch (IOException var13) {
                try {
                    config = Config.fromJSON(this.redissonProperties.getConfig());
                } catch (IOException var12) {
                    throw new IllegalArgumentException("Can't parse config", var12);
                }
            }
         //2、判断spring.redis.redisson是否有file配置
        } else if (this.redissonProperties.getFile() != null) {
            try {
                InputStream is = this.getConfigStream();
                config = Config.fromYAML(is);
            } catch (IOException var11) {
                try {
                    InputStream is = this.getConfigStream();
                    config = Config.fromJSON(is);
                } catch (IOException var10) {
                    throw new IllegalArgumentException("Can't parse config", var10);
                }
            }
         //3、判断spring.redis.redisson是否有sentinel配置
        } else if (this.redisProperties.getSentinel() != null) {
            nodesMethod = ReflectionUtils.findMethod(Sentinel.class, "getNodes");
            Object nodesValue = ReflectionUtils.invokeMethod(nodesMethod, this.redisProperties.getSentinel());
            String[] nodes;
            if (nodesValue instanceof String) {
                nodes = this.convert(Arrays.asList(((String)nodesValue).split(",")));
            } else {
                nodes = this.convert((List)nodesValue);
            }

            config = new Config();
            ((SentinelServersConfig)config.useSentinelServers().setMasterName(this.redisProperties.getSentinel().getMaster()).addSentinelAddress(nodes).setDatabase(this.redisProperties.getDatabase()).setConnectTimeout(timeout)).setPassword(this.redisProperties.getPassword());
        } else {
            //4、什么都没配置的话就走redisson默认配置
            Method method;
            if (clusterMethod != null && ReflectionUtils.invokeMethod(clusterMethod, this.redisProperties) != null) {
                //reids集群走这里
                Object clusterObject = ReflectionUtils.invokeMethod(clusterMethod, this.redisProperties);
                method = ReflectionUtils.findMethod(clusterObject.getClass(), "getNodes");
                List<String> nodesObject = (List)ReflectionUtils.invokeMethod(method, clusterObject);
                String[] nodes = this.convert(nodesObject);
                config = new Config();
                ((ClusterServersConfig)config.useClusterServers().addNodeAddress(nodes).setConnectTimeout(timeout)).setPassword(this.redisProperties.getPassword());
            } else {
                 //单机版reids走这里
                config = new Config();
                String prefix = "redis://";
                method = ReflectionUtils.findMethod(RedisProperties.class, "isSsl");
                if (method != null && (Boolean)ReflectionUtils.invokeMethod(method, this.redisProperties)) {
                    prefix = "rediss://";
                }

                ((SingleServerConfig)config.useSingleServer().setAddress(prefix + this.redisProperties.getHost() + ":" + this.redisProperties.getPort()).setConnectTimeout(timeout)).setDatabase(this.redisProperties.getDatabase()).setPassword(this.redisProperties.getPassword());
            }
        }

看完代码以后,发现是真简单,直接把第四步的拿出来自己改改就好了。下面就是半天的劳动成果(不想把参数放在yaml中配置了,有需要可自己改)。

import com.alibaba.excel.util.ListUtils;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.ClusterServersConfig;
import org.redisson.config.Config;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Method;
import java.util.List;

@Configuration
public class RedissonConfig {

    private  RedisProperties redisProperties;



    public RedissonConfig(RedisProperties redisProperties) {
        this.redisProperties=redisProperties;

    }
    /**
     * redisson java配置,取yaml中redis的链接配置
     * 不支持在yaml中配置,如想在yaml中单独配置redisson,请删掉此类。
     * RedissonAutoConfiguration
     * @return {@link RedissonClient}
     */
    @Bean(destroyMethod = "shutdown")
    RedissonClient redisson()  {
        Method clusterMethod = ReflectionUtils.findMethod(RedisProperties.class, "getCluster");
        if(clusterMethod==null){
            return null;
        }
        Object clusterObject = ReflectionUtils.invokeMethod(clusterMethod, this.redisProperties);
        if(clusterObject==null){
            //单机模式配置
            Config config = new Config();
            config.setNettyThreads(2);
            config.setThreads(2);
            String prefix = "redis://";
            Method method = ReflectionUtils.findMethod(RedisProperties.class, "isSsl");
            if (method != null && (Boolean)ReflectionUtils.invokeMethod(method, this.redisProperties)) {
                prefix = "rediss://";
            }

            (config.useSingleServer().setAddress(prefix + this.redisProperties.getHost() + ":" + this.redisProperties.getPort()).setConnectTimeout(1000)).setDatabase(this.redisProperties.getDatabase()).setPassword(this.redisProperties.getPassword());
            return Redisson.create(config);
        }
        Method  method = ReflectionUtils.findMethod(clusterObject.getClass(), "getNodes");
        if(method==null){
            return null;
        }
        List<String> nodesObject = (List)ReflectionUtils.invokeMethod(method, clusterObject);
        if(nodesObject==null){
            return null;
        }
        String[] nodes = this.convert(nodesObject);
        Config  config = new Config();
        //集群模式参数配置
        ClusterServersConfig clusterServersConfig = config.useClusterServers().addNodeAddress(nodes).setConnectTimeout(1000);
        clusterServersConfig.setPassword(this.redisProperties.getPassword());
        clusterServersConfig.setSlaveConnectionMinimumIdleSize(2);
        clusterServersConfig.setMasterConnectionMinimumIdleSize(2);
        clusterServersConfig.setMasterConnectionPoolSize(2);

        config.setNettyThreads(2);
        config.setThreads(2);
        return Redisson.create(config);

    }
    private String[] convert(List<String> nodesObject) {
        List<String> nodes = ListUtils.newArrayListWithExpectedSize(nodesObject.size());
        for (String node:nodesObject) {
            if (!node.startsWith("redis://") && !node.startsWith("rediss://")) {
                nodes.add("redis://" + node);
            } else {
                nodes.add(node);
            }
        }
        return nodes.toArray(new String[nodes.size()]);
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值