社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
问题简述
使用dubbo-spring-boot-starter
无法正确处理多 Dubbo 配置
,而原始dubbo
可以正确处理
以下描述摘自Dubbo 外部化配置(Externalized Configuration)
Dubbo
@Service
和@Reference
允许 Dubbo 应用关联ApplicationConfig
Bean 或者指定多个RegistryConfig
Bean 等能力。换句话说,Dubbo 应用上下文中可能存在多个ApplicationConfig
等 Bean定义。
为了适应以上需要,因此从Dubbo2.5.9
开始,@EnableDubboConfig
支持多 Dubbo 配置 Bean 绑定,同时按照业界规约标准,与单 Dubbo 配置 Bean 绑定约定不同,配置属性前缀均为英文复数形式:
详情请参考 :https://github.com/alibaba/dubbo/issues/1141
使用使用官方https://github.com/apache/dubbo-spring-boot-project
提供的dubbo-spring-boot-starter
实践上述配置时会出现一些问题。而使用原始dubbo能正常处理。现描述如下,也请业界大佬帮忙解答是否为bug,亦或另有深意。
<properties>
<spring-boot.version>2.1.6.RELEASE</spring-boot.version>
<dubbo.version>2.7.3</dubbo.version>
</properties>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>
<properties>
<spring-boot.version>2.1.6.RELEASE</spring-boot.version>
<dubbo.version>2.7.3</dubbo.version>
</properties>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>${dubbo.version}</version>
</dependency>
使用dubbo-spring-boot-starter
处理如下配置
dubbo.consumers.user.application.name=consumers-user-application
dubbo.consumers.web.application.name=consumers-web-application
会报错:
Failed to bind properties under 'dubbo.consumers.web' to org.apache.dubbo.config.ConsumerConfig:
Reason: Duplicate Config found for ApplicationConfig, you should use only one unique ApplicationConfig for one application.
原始dubbo与dubbo-spring-boot-starter处理dubbo.consumers.*
的异同代码说明
1. 原始dubbo使用org.apache.dubbo.config.spring.context.properties.DefaultDubboConfigBinder
处理配置绑定。而dubbo-spring-boot-starter使用org.apache.dubbo.spring.boot.autoconfigure.BinderDubboConfigBinder
。如下图:
2. 处理ConsumerConfig配置的异同
配置ConsumerConfig时会调用ConsumerConfig父类AbstractInterfaceConfig#setApplication方法配置ApplicationConfig。此时会使用org.apache.dubbo.config.context.ConfigManager#checkDuplicate
对Application配置做重复校验。
dubbo.consumers.user.application.name=consumers-user-application
dubbo.consumers.web.application.name=consumers-web-application
根据org.apache.dubbo.config.context.ConfigManager#checkDuplicate
的处理逻辑始终都具有唯一性,从而正常校验通过。详细参考源码。
dubbo.consumers.*.application.*
配置时,org.apache.dubbo.config.context.ConfigManager#checkDuplicate
校验第二ConsumerConfig的ApplicationConfig时就会失败,从而报错。以上说明的代码跟踪截图如下:
第1次处理"dubbo.consumers.user.application.name=consumers-user-application",正常通过
第2次处理"dubbo.consumers.web.application.name=consumers-web-application",同样正常通过
第2次处理"dubbo.consumers.web.application.name=consumers-web-application",失败报错。因为此时调用ConfigManager时,内部属性application保留了第一次调用时的application,且有完整的属性,所以调用checkDuplicate方法时报错。
其它类似dubbo.(*s).*.application.*
配置同样会包类似的错误
使用dubbo-spring-boot-starter
处理如下配置
dubbo.applications.app1.name=applications-app1
dubbo.applications.app2.name=applications-app1
会报错:
java.lang.IllegalStateException: There are more than one instances of ApplicationConfig, whose bean definitions : [Root bean: class [org.apache.dubbo.config.ApplicationConfig]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null, Root bean: class [org.apache.dubbo.config.ApplicationConfig]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null]
...
...
dubbo-spring-boot-starter处理dubbo配置时,使用了org.apache.dubbo.spring.boot.beans.factory.config.DubboConfigBeanDefinitionConflictProcessor
类处理ApplicationConfig
配置冲突。
分析源码后,很费解其处理逻辑,根据逻辑,完全就排斥dubbo.applications.*
的配置。
代码跟踪截图如下:
org.apache.dubbo.config.AbstractConfig#equals
方法中为什么Exception情况下会返回true。
关于多 Dubbo 配置 Bean 绑定,官方可参考的资源如下:
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!