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

时间: 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所示:
这里写图片描述
图1
redisConnectionFactory 有两个实现类, 具体如图2所示:
这里写图片描述
图2

因为Sprig Boot 2.x 使用的是LettuceConnnection, 所以会使用LettuceConnectionFactory,那么这个工厂类是在哪里是初始化呢?
是在LettuceConnectionConfiguration 中进行初始化的, 具体如图3所示:
这里写图片描述
图3

接下来, 在看看LettuceConnnection 是在哪里进行切换数据库的, 具体如图4所示:
这里写图片描述
图4

红框部分就是上述打印出来的错误, 那么, 问题就定位到了, 看看上述参数如何设置的。
这里写图片描述
图5

从上图5中可以知道, 是在构造方法中进行初始化的。 问题又回到了LettuceConnectionFactory里面,具体是在图6所示位置创建。
这里写图片描述
这里写图片描述
图6

从图6可以看到shareNativeConnection 这个变量决定是否要创建一个新的连接, 这个值默认是true 共享连接。
具体如何设置呢?请看图7。
这里写图片描述
到此就分析完成个过程了,接下来看看解决方案。

解决方法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就都解决完成。

没有更多推荐了,返回首页