BeanNotOfRequiredTypeException:记一个不当的dubbo引用导致的tomcat启动报错


今天下午在部署服务时,发现tomcat服务无法启动。异常:org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'platformAccountService' must be of type [com.emaxcard.account.modules.account.service.PlatformAccountService], but was actually of type [com.alibaba.dubbo.common.bytecode.proxy16]   堆栈详细信息如下:

2021-11-25 14:49:21.411 [ERROR] [localhost-startStop-1] [org.springframework.web.context.ContextLoader:331] Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'manageFeeController': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'platformAccountService' must be of type [com.emaxcard.account.modules.account.service.PlatformAccountService], but was actually of type [com.alibaba.dubbo.common.bytecode.proxy16]
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:307)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
--
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:1017)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:993)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:652)
    at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1127)
    at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:2021)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'platformAccountService' must be of type [com.emaxcard.account.modules.account.service.PlatformAccountService], but was actually of type [com.alibaba.dubbo.common.bytecode.proxy16]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:376)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:445)
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:419)
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:544)
    at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:155)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:304)
    ... 26 more

当前工程中的platformAccountService是一个dubbo服务接口类。dubbo配置文件里定义了这个bean。

<dubbo:reference id="platformAccountService" interface="com.emaxcard.account.modules.service.PlatformAccountService"
timeout="5000"/>

其他dubbo服务也都是这么定义的,怎么今天重启服务突然出现这个BeanNotOfRequiredTypeException异常了呢?

原来,错误中提到的ManageFeeController中,import引入的platformAccountService类型是com.emaxcard.account.modules.account.service.PlatformAccountService, 而dubbo配置中定义的类型是 com.emaxcard.account.modules.service.PlatformAccountService。 定睛细看,两者的package是不同的,前者package中多了一级account。难怪呢,既然为bean引入的是com..XxxService,那么编译器认定bean的类型就应该是com..XxxService类型,实际却发现bean的类型在context里是dubbo代理类。

import com.emaxcard.account.modules.account.service.PlatformAccountService;
import com.emaxcard.account.modules.account.vo.ManageFeeAccountVo;

@Controller
public class ManageFeeController {

    @Resource
    private PlatformAccountService platformAccountService;
    
    ...
}

为什么程序编译没报错呢?原来,所依赖的rpc服务jar包里,还真存在不同package下的两个PlatformAccountService接口类。

这样的情况真的会误导人呀!那么,为什么会存在两个PlatformAccountService接口类呢?原来,是负责这个接口的同学重新整理了api接口,将这个PlatformAccountService放在了新的package下,却没有删掉原来package及package下的这些类文件,殊不知却为调用方带来了麻烦。