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下的这些类文件,殊不知却为调用方带来了麻烦。