天天看點

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所示:

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就都解決完成。

繼續閱讀