BeanNotOfRequiredTypeException:记一个不当的dubbo引用导致的tomcat服务启动报错
今天下午在部署服务时,发现tomcat服务无法启动。异常:org.springframework.beans.factory.BeanCreationException:Error creating bean with name 'manageFeeController': Injection of resource dependencies failed. 就是说,因资源注入问题导致容器创建bean失败。再往后看,引发这个BeanCreation异常是因为这个错误: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] 译为:名为 ‘platformAccountService’ 的bean应该是[com.emaxcard.account.modules.account.service.PlatformAccountService]类型,而实际上却是dubbo代理类。 详细堆栈信息如下:
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及其中的这些接口类和dto类,殊不知却为调用方带来了麻烦。
当看到一些不好的代码时,会发现我还算优秀;当看到优秀的代码时,也才意识到持续学习的重要!--buguge
本文来自博客园,转载请注明原文链接:https://www.cnblogs.com/buguge/p/15620966.html