欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring cloud 和 Spring Boot 升级到F版和2.x遇到的问题。

程序员文章站 2022-05-22 09:45:09
...

时间: 2018-08-02
今天一个朋友升级Spring Cloud 到F版 出现的问题,

1、问题一
1)、大概错误:

is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘org.springframework.boot.actuate.autoconfigure.jdbc.DataSourceHealthIndicatorAutoConfiguration’: Bean instantiation via constructor failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.actuate.autoconfigure.jdbc.DataSourceHealthIndicatorAutoConfiguration$$EnhancerBySpringCGLIB$$e550fa6]: Constructor threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘dataSource’: Post-processing of FactoryBean’s singleton object failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘scopedTarget.dataSource’ defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Initialization of bean failed;
nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerInvoker’: Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘dataSource’: Post-processing of FactoryBean’s singleton object failed; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name ‘scopedTarget.dataSource’: Requested bean is currently in creation: Is there an unresolvable circular reference?

2)解决方案: 将spring boot 升级到2.0.4 即可解决
相关解决问题地址: https://github.com/spring-cloud/spring-cloud-commons/issues/384
实际是在spring 5.0.8 中的获取bean 进行调整
org\springframework\spring-beans\5.0.8.RELEASE\spring-beans-5.0.8.RELEASE.jar!\org\springframework\beans\factory\support\AbstractBeanFactory.class

2、问题二
1)、出现的spring-data-redis 的切库问题:
Selecting a new database not supported due to shared connection. Use separate ConnectionFactorys to work with multiple databases
原因是 spring boot 2.x 默认是用的是 LettuceConnection , 这个是使用共享连接的,所以会出现上面的错误。

2)定位和解决方案:
通过访问地址:
https://docs.spring.io/spring-data/redis/docs/2.1.0.M3/reference/html/#new-in-2.0.0
可以到2.0 的特性信息,具体如图1所示:
Spring cloud 和 Spring Boot 升级到F版和2.x遇到的问题。
图1
redisConnectionFactory 有两个实现类, 具体如图2所示:
Spring cloud 和 Spring Boot 升级到F版和2.x遇到的问题。
图2

因为Sprig Boot 2.x 使用的是LettuceConnnection, 所以会使用LettuceConnectionFactory,那么这个工厂类是在哪里是初始化呢?
是在LettuceConnectionConfiguration 中进行初始化的, 具体如图3所示:
Spring cloud 和 Spring Boot 升级到F版和2.x遇到的问题。
图3

接下来, 在看看LettuceConnnection 是在哪里进行切换数据库的, 具体如图4所示:
Spring cloud 和 Spring Boot 升级到F版和2.x遇到的问题。
图4

红框部分就是上述打印出来的错误, 那么, 问题就定位到了, 看看上述参数如何设置的。
Spring cloud 和 Spring Boot 升级到F版和2.x遇到的问题。
图5

从上图5中可以知道, 是在构造方法中进行初始化的。 问题又回到了LettuceConnectionFactory里面,具体是在图6所示位置创建。
Spring cloud 和 Spring Boot 升级到F版和2.x遇到的问题。
Spring cloud 和 Spring Boot 升级到F版和2.x遇到的问题。
图6

从图6可以看到shareNativeConnection 这个变量决定是否要创建一个新的连接, 这个值默认是true 共享连接。
具体如何设置呢?请看图7。
Spring cloud 和 Spring Boot 升级到F版和2.x遇到的问题。
到此就分析完成个过程了,接下来看看解决方案。

解决方法1:

@Configuration
@AutoConfigureAfter(RedisAutoConfiguration.class)
public class RedisCacheAutoConfiguration {

    @Bean
    public RedisTemplate<String, Serializable> redisCacheTemplate(LettuceConnectionFactory redisConnectionFactory) {

        redisConnectionFactory.setShareNativeConnection(false);
        RedisTemplate<String, Serializable> template = new RedisTemplate<>();
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}

解决方法2:
自己构建LettuceConnectionFactory

@Configuration
public class Factory{
    @Bean
    @ConditionalOnClass(RedisConnectionFactory.class)
    public LettuceConnectionFactory redisConnectionFactory(
            ClientResources clientResources) throws UnknownHostException {

        // 这里创建factory, 具体创建需要的参数参考图3
    }
}

到此整个升级过程的遇到的bug就都解决完成。