springboot 集成 redisTemplate 配置多个数据源

springboot版本为 1.5.10.RELEASE

 一、依赖

 <!--redis依赖-->
 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-redis</artifactId>
 </dependency>
 <!--加载yml配置-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.47</version>
</dependency>

 二、yml配置

#集群版配置
com:
  wan:
    redis:
      pool:
        maxTotal: 100
        maxIdle: 10
        maxWaitMillis: 3000
      cluster:
        connectionTimeout: 3000
        soTimeout: 3000
        maxRedirections: 5
        jedisClusterNodes: #你的IP:port,你的IP:port(IP:PORT逗号分隔)
      #如果为多个集群 一次类推
      #cluster1:
      #  connectionTimeout:
      #  soTimeout:
      #  maxRedirections:
      #  jedisClusterNodes:
      #pool1:
      #  maxTotal: 100
      #  maxIdle: 10
      #  maxWaitMillis: 3000
#单机版配置
  redis:
    only:
      client:
        host-name: 127.0.0.1
        port: 6379
      pool:
        max-total: 100
        max-idle: 10
        max-wait-millis: 3000

注意上面yml前缀要和这里相同才会加载到properties类中

三、

  1、单机版连接池properties (JedisClientPoolProperties)

/**
 * 单机版properties
 * @author 战猿点
 * @date 2018/5/14 14:25
 */
@Data
public class JedisClientPoolProperties {

    private int maxTotal;
    private int maxIdle;
    private int maxWaitMillis;
}

2、单机版配置信息(redisproperties)

/**
 * @author 战猿点
 * @date 2018/5/14 14:23
 */
@Data
public class JedisClientProperties {

    private int port;
    private String hostName;
    private int timeout;

}

四、

   1、集群版redis连接池(JedisClusterConfigProperties)

/**
 * @author 战猿点
 * @date 2018/5/14 14:25
 */
public class JedisClusterPoolProperties {

    private int maxTotal;
    private int maxIdle;
    private int maxWaitMillis;

    public int getMaxTotal() {
        return maxTotal;
    }

    public void setMaxTotal(int maxTotal) {
        this.maxTotal = maxTotal;
    }

    public int getMaxIdle() {
        return maxIdle;
    }

    public void setMaxIdle(int maxIdle) {
        this.maxIdle = maxIdle;
    }

    public int getMaxWaitMillis() {
        return maxWaitMillis;
    }

    public void setMaxWaitMillis(int maxWaitMillis) {
        this.maxWaitMillis = maxWaitMillis;
    }

   2、集群版redis配置信息(JedisClusterConfigProperties)

/**
 * Jedis集群配置类
 *
 * @author 战猿点
 */
public class JedisClusterConfigProperties {
    private int connectionTimeout;
    private int soTimeout;
    private int maxRedirections;
    private List<String> jedisClusterNodes;

    public int getConnectionTimeout() {
        return connectionTimeout;
    }

    public void setConnectionTimeout(int connectionTimeout) {
        this.connectionTimeout = connectionTimeout;
    }

    public int getSoTimeout() {
        return soTimeout;
    }

    public void setSoTimeout(int soTimeout) {
        this.soTimeout = soTimeout;
    }

    public int getMaxRedirections() {
        return maxRedirections;
    }

    public void setMaxRedirections(int maxRedirections) {
        this.maxRedirections = maxRedirections;
    }

    public List<String> getJedisClusterNodes() {
        return jedisClusterNodes;
    }

    public void setJedisClusterNodes(List<String> jedisClusterNodes) {
        this.jedisClusterNodes = jedisClusterNodes;
    }
}

五、初始化单机版jedisConfig

/**
 * redis单机版配置
 * @author 战猿点
 * @date 2018/5/11 15:50
 */
@Configuration
public class JedisClientConfig {

    @Bean
    @ConfigurationProperties(prefix = "com.redis.only.pool")
    public JedisClientPoolProperties jedisClientPoolProperties(){
        return new JedisClientPoolProperties();
    }

    @Bean
    @ConfigurationProperties(prefix = "com.redis.only.client")
    public JedisClientProperties jedisClientProperties(){
        return new JedisClientProperties();
    }

    /**
     * 单节点
     * @return
     */
    @Bean
    public JedisConnectionFactory defaultJedisConnectionFactory(){
        //如果什么参数都不设置,默认连接本地6379端口
        JedisClientPoolProperties jedisClientPoolProperties = jedisClientPoolProperties();
        JedisClientProperties jedisClientProperties = jedisClientProperties();
        JedisConnectionFactory factory = new JedisConnectionFactory();
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(jedisClientPoolProperties.getMaxIdle());
        jedisPoolConfig.setMaxTotal(jedisClientPoolProperties.getMaxTotal());
        jedisPoolConfig.setMaxWaitMillis(jedisClientPoolProperties.getMaxWaitMillis());

        factory.setPort(jedisClientProperties.getPort());
        factory.setHostName(jedisClientProperties.getHostName());
        factory.setTimeout(jedisClientProperties.getTimeout());
        factory.setPoolConfig(jedisPoolConfig);
        return factory;
    }

    @Bean
    public RedisTemplate<String,Object> defaultRedisTemplate(JedisConnectionFactory defaultJedisConnectionFactory){
        //创建一个模板类
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        //将刚才的redis连接工厂设置到模板类中
        template.setConnectionFactory(defaultJedisConnectionFactory);
        StringRedisSerializer hashKeySerializer = new StringRedisSerializer();
        template.setKeySerializer(hashKeySerializer);
        template.setHashKeySerializer(hashKeySerializer);
        return template;
    }

    @Bean
    public StringRedisTemplate defaultStringRedisTemplate(JedisConnectionFactory defaultJedisConnectionFactory){
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setConnectionFactory(defaultJedisConnectionFactory);
        return stringRedisTemplate;
    }

    /**
     * 序列化不同(对象)
     * @param defaultRedisTemplate
     * @return
     */
    @Bean
    public RedisUtil defaultRedisUtil(RedisTemplate<String,Object> defaultRedisTemplate){
        return new RedisUtil(defaultRedisTemplate);
    }

    /**
     * (可视的数据)
     * @param defaultStringRedisTemplate
     * @return
     */
    @Bean
    public StringTemplateRedisUtil defaultStringTemplateRedisUtil(StringRedisTemplate defaultStringRedisTemplate){
        return new StringTemplateRedisUtil(defaultStringRedisTemplate);
    }

六、初始化集群版jedisConfig

  

/**
 * 集群版
 * @author 万明宇(战猿点)
 * @date 2018/7/29 18:03
 */
@Configuration
public class JedisClusterConfig {

    @Bean
    @ConfigurationProperties(prefix = "com.wan.redis.pool")
    public JedisClusterPoolProperties jedisClusterPoolProperties(){
        return new JedisClusterPoolProperties();
    }
    @Bean
    @ConfigurationProperties(prefix = "com.wan.redis.cluster")
    public JedisClusterConfigProperties jedisClusterConfigProperties(){
        return new JedisClusterConfigProperties();
    }



    @Bean
    public JedisConnectionFactory jedisConnectionFactoryCluster1(){
        JedisClusterPoolProperties jedisClusterPoolProperties = jedisClusterPoolProperties();
        JedisClusterConfigProperties jedisClusterConfigProperties = jedisClusterConfigProperties();
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(jedisClusterPoolProperties.getMaxIdle());
        jedisPoolConfig.setMaxTotal(jedisClusterPoolProperties.getMaxTotal());
        jedisPoolConfig.setMaxWaitMillis(jedisClusterPoolProperties.getMaxWaitMillis());

        //集群配置
        RedisClusterConfiguration configuration = new RedisClusterConfiguration(jedisClusterConfigProperties.getJedisClusterNodes());
        configuration.setMaxRedirects(jedisClusterConfigProperties.getMaxRedirections());

        JedisConnectionFactory factory = new JedisConnectionFactory(configuration, jedisPoolConfig);
        factory.setTimeout(jedisClusterConfigProperties.getSoTimeout());
        return factory;
    }

    /**
     * redisClusterTemplateCluster1
     * @param jedisConnectionFactoryCluster1 参数名为beanName
     * @return
     */
    @Bean
    public RedisTemplate<String,Object> redisClusterTemplateCluster1(JedisConnectionFactory jedisConnectionFactoryCluster1){
        //创建一个模板类
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        //将刚才的redis连接工厂设置到模板类中
        template.setConnectionFactory(jedisConnectionFactoryCluster1);
        //初始化redis key中的序列化方式 StringRedisSerializer
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        //初始化redis value中的序列化方式 fastjson序列化
        GenericFastJsonRedisSerializer serializer = new GenericFastJsonRedisSerializer();
        template.setHashValueSerializer(serializer);
        template.setValueSerializer(serializer);
        return template;
    }

    @Bean
    public StringRedisTemplate stringRedisTemplateCluster1(JedisConnectionFactory jedisConnectionFactoryCluster1){
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setConnectionFactory(jedisConnectionFactoryCluster1);
        return  stringRedisTemplate;
    }

    /**
     * 序列化不同(对象)
     * @param redisClusterTemplateCluster1
     * @return
     */
    @Bean
    public RedisUtil redisUtilCluster1(RedisTemplate<String,Object> redisClusterTemplateCluster1){
        return new RedisUtil(redisClusterTemplateCluster1);
    }


    /**
     * (可视的数据)
     * @param stringRedisTemplateCluster1
     * @return
     */
    @Bean
    public StringTemplateRedisUtil StringRedisUtilCluster1(StringRedisTemplate stringRedisTemplateCluster1){
        return new StringTemplateRedisUtil(stringRedisTemplateCluster1);
    }

七、 必须要移除springboot的自动装配redis

 作者踩到的坑(前提如果不移除springboot自动装配redis)

 1:如果connection配置两个方法名不同(beanName不同),则会报以下错误)

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of method redisTemplate in org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration$RedisConfiguration required a single bean, but 2 were found:
	- handRoomJedisConnectionFactory: defined by method 'handRoomJedisConnectionFactory' in class path resource [com/example/redisdemo/configs/HandroomClientConfig.class]
	- jedisConnectionFactoryDeityChop: defined by method 'jedisConnectionFactoryDeityChop' in class path resource [com/example/redisdemo/configs/JedisClusterConfig.class]


Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

   2:如果connection配置两个(或者一个)方法名相同(beanName相同)则会只加载一种数据源

 解决办法:

@SpringBootApplication(exclude = {
        RedisAutoConfiguration.class,  //此处为springboot自动装配,需要移除否则会报错或者只能单数据源
        RedisRepositoriesAutoConfiguration.class  //此处为springboot自动装配,需要移除否则会报错或者只能单数据源
})
public class RedisDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(RedisDemoApplication.class, args);
    }

}

八、需要用到的工具类

  1  RedisUtil  如不需要请注释与其相关的代码 如有需要请到GitHub下载源码

  2.  StringTemplateRedisUtil  如不需要请注释与其相关的代码 如有需要请到GitHub下载源码


作者在初次配置多个数据源时,因为未移除springboot的自动装配,但是通过源码找到了其他方法就是在自定义JeidscConfig里面继承 RedisAutoConfiguration 这个类。继承后就算不移除自动装配也会读取两种不通的数据源。但总是感觉怪怪的。还是移除自动装配RedisAutoConfiguration比较稳当.

/**
 * redis单机版配置
 * @author 战猿点
 * @date 2018/5/11 15:50
 */
@Configuration
public class JedisClientConfig extends RedisAutoConfiguration {

//........
}

 

个人认为继承 RedisAutoConfiguration 这个之后自动装配会默认加载我们自定义写的子类也就是configs下面的jedisClientConfig和jedisClustterConfig  后续作者还会探究为什么。如有大佬请给与提示谢谢。

 

哈哈,好了以上就是作者所踩的坑,以上如有错误,请大佬们及时纠正,谢谢。

GitHub地址为: https://github.com/warApePoint/redis-demo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猿道apeto

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值