dubbo註冊中心佔位符無法解析問題
前面分析了dubbo註冊中心佔位符無法解析的問題。
並給出了2種解決辦法:
- 降低mybatis-spring的版本至2.0.1及以下
- 自定義MapperScannerConfigurer,設定processPropertyPlaceHolders為false
不過,末尾遺留了一個疑問,這篇文章就來分析下這個問題
合併前的老專案二使用的就是mybatis-spring-2.0.3.jar,但是他沒有報【UnknownHostException: ${zk.address}】,也沒有自定義MapperScannerConfigurer設定processPropertyPlaceHolders為false
1、問題分析
既然老專案二正常,那麼就拿它來debug瞧瞧。
根據前面的經驗,在如下位置加上斷點,debug走起
org.springframework.context.support.PropertySourcesPlaceholderConfigurer#postProcessBeanFactory
com.alibaba.dubbo.config.RegistryConfig#setAddress
一番debug走下來,發現RegistryConfig#setAddress確實傳的是apollo上配置的值。
也就是說PropertySourcesPlaceholderConfigurer在RegistryConfig物件初始化之前就調了。
這不打臉了嗎?前面一頓分析,解決方法都給出來了, ̄□ ̄||
繼續往前分析下,看看呼叫棧,RegistryConfig是因為ReferenceBean#afterPropertiesSet的執行,而被建立的。那麼,再增加一個斷點
com.alibaba.dubbo.config.spring.ReferenceBean#afterPropertiesSet
多次debug發現,進入ReferenceBean#afterPropertiesSet的時候,在如下位置其實是報錯了
public void afterPropertiesSet() throws Exception {
// ...此處省略若干程式碼...
if (getApplication() == null
&& (getConsumer() == null || getConsumer().getApplication() == null)) {
Map<String, ApplicationConfig> applicationConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ApplicationConfig.class, false, false);
// !! BeanFactoryUtils.beansOfTypeIncludingAncestors報錯了 !!
if (applicationConfigMap != null && applicationConfigMap.size() > 0) {
// ...此處省略若干程式碼...
}
// ...此處省略若干程式碼...
}
}
完整的錯誤訊息
org.springframework.beans.factory.BeanCreationException: Error creating bean with name '${dubbo.application.name}': Error setting property values; nested exception is org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:
PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'name' threw exception; nested exception is java.lang.IllegalStateException: Invalid name="${dubbo.application.name}" contains illegal character, only digit, letter, '-', '_' or '.' is legal.
這不過這個錯誤,Spring最終沒有丟擲來,不僅沒丟擲異常,還destroy了這個建立了一半的bean
並在後面,列印了毫不起眼的debug級別日誌
DEBUG o.s.b.f.s.DefaultListableBeanFactory - Bean creation exception on non-lazy FactoryBean type check: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jobCallback': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '${dubbo.application.name}': Error setting property values; nested exception is org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:
PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'name' threw exception; nested exception is java.lang.IllegalStateException: Invalid name="${dubbo.application.name}" contains illegal character, only digit, letter, '-', '_' or '.' is legal.
原來還有這種騷操作!
MapperScannerConfigurer --> 建立 --> 未解析dubbo.application.name,建立ApplicationConfig異常 --> 銷燬掉 延後再建立 --> PropertySourcesPlaceholderConfigurer --> 延後建立
再回過頭來看了下 老專案二 的spring-dubbo-common.xml裡面的配置,它在配置的時候 用的${dubbo.application.name},而不是具體值!
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<dubbo:application name="${dubbo.application.name}"/>
<!--
新專案裡面,我寫的是這樣子的
<dubbo:application name="dc-dubbo"/>
-->
<dubbo:registry address="${zk.address}" protocol="zookeeper"/>
<dubbo:protocol name="dubbo" port="21660" threadpool="fixed" threads="300"/>
</beans>
啊!!我有一種負負得正、錯錯得對的感覺!!
2、解決辦法
2.1、方法三
xml改成
<dubbo:application name="${dubbo.application.name}"/>
並增加dubbo.application.name的配置