dubbo註冊中心佔位符無法解析問題(二)

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走起

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="//www.springframework.org/schema/beans"
       xmlns:xsi="//www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="//code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="//www.springframework.org/schema/beans
       //www.springframework.org/schema/beans/spring-beans.xsd
       //code.alibabatech.com/schema/dubbo
       //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的配置

Tags: