時間: 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所示:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNvwVZ2x2bzNXak9CX90TQNNkRrFlQKBTSvwFbslmZvwFMwQzLcVmepNHdu9mZvwFVywUNMZTY18CX052bm9CX9UUbaVnVuVmb1IjYvB3MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2LcRHelR3LcJzLctmch1mclRXY39jNzkTM1MTMyIjMwgDM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
圖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就都解決完成。