Java Spring - Bean 创建中的奇怪错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1468657/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 12:37:55  来源:igfitidea点击:

Spring - Weird Error in Bean Creation

javaspringdependency-injectionjava-ee-6cglib

提问by peakit

Any idea why I am getting this exception?

知道为什么我会收到此异常吗?

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myService' defined in class path resource [context.xml]: Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type [$Proxy54 implementing org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised,net.sf.cglib.proxy.Factory,org.springframework.beans.factory.InitializingBean] to required type [com.mycompany.service.dao.MyDAO] for property 'myDAO'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [$Proxy54 implementing org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised,net.sf.cglib.proxy.Factory,org.springframework.beans.factory.InitializingBean] to required type [com.mycompany.service.dao.MyDAO] for property 'myDAO': no matching editors or conversion strategy found
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:480)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.run(AbstractAutowireCapableBeanFactory.java:409)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:264)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:671)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:610)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:499)
    ... 36 more
Caused by: java.lang.IllegalArgumentException: Cannot convert value of type [$Proxy54 implementing org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised,net.sf.cglib.proxy.Factory,org.springframework.beans.factory.InitializingBean] to required type [com.mycompany.service.dao.MyDAO] for property 'myDAO': no matching editors or conversion strategy found
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:231)
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:138)
    at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:386)
... 62 more

采纳答案by SingleShot

I suspect that if ProdMiscDAOwas an interface (is it?) you would not have this error. I believe you probably have a class that is getting proxied using cglib under the hood, performing magic, etc. and in the end it cannot be safely cast to a paramter in a setter or constructor. Try programming to an interface and see if the error goes away.

我怀疑如果ProdMiscDAO是一个接口(是吗?),你就不会出现这个错误。我相信您可能有一个类在后台使用 cglib 进行代理、执行魔术等,但最终它无法安全地转换为 setter 或构造函数中的参数。尝试对接口编程,看看错误是否消失。

Update: ProdMiscDAOis not an interface. It is a class that extends SqlMappedClientDaoSupport.

更新ProdMiscDAO不是接口。它是一个扩展的类SqlMappedClientDaoSupport

Given this, I recommend trying this:

鉴于此,我建议尝试这样做:

  1. Rename ProdMiscDAOto SqlMappedProdMiscDAO.
  2. Extract an interface from SqlMappedProdMiscDAOnamed ProdMiscDAO(e.g. "class SqlMappedProdMiscDAO implements ProdMiscDAO")
  3. Go through all your code that uses SqlMappedProdMiscDAOand change it to use ProdMiscDAO.
  4. Configure spring to instantiate a SqlMappedProdMiscDAO, wiring it all the classes that need it.
  1. 重命名ProdMiscDAOSqlMappedProdMiscDAO.
  2. SqlMappedProdMiscDAO命名ProdMiscDAO(例如“ class SqlMappedProdMiscDAO implements ProdMiscDAO”)中提取接口
  3. 浏览所有使用的代码SqlMappedProdMiscDAO并将其更改为使用ProdMiscDAO.
  4. 配置 spring 以实例化 a SqlMappedProdMiscDAO,将它连接到所有需要它的类。

This allows your DAO implementation to still extend SqlMappedClientDaoSupportbut also to have an interface. After switching over all classes to use the interface instead of the class, Spring will not have to use cglib to proxy your DAO and the error should go away.

这允许您的 DAO 实现仍然扩展SqlMappedClientDaoSupport但也有一个接口。在切换所有类以使用接口而不是类后,Spring 将不必使用 cglib 来代理您的 DAO,错误应该会消失。

回答by duffymo

Spring uses proxies, generated at run-time from interfaces, to do things like transactions, aspects, etc. The proper Spring idiom for objects like DAOs, services, etc. is to start with an interface and create a concrete implementation. Once you have that, you're free to generate proxies from the interface as needed.

Spring 使用在运行时从接口生成的代理来执行事务、方面等操作。对于 DAO、服务等对象,Spring 的正确习惯用法是从接口开始并创建具体实现。一旦你有了它,你就可以根据需要从界面中自由地生成代理。

So of course you'll have a concrete DAO implementation, and that's free to extend SqlMapClientDaoSupport if you wish, but also create an interface that has your methods.

所以当然你会有一个具体的 DAO 实现,如果你愿意,可以自由扩展 SqlMapClientDaoSupport,但也可以创建一个包含你的方法的接口。

Be sure that you really need to extend SqlMapClientDaoSupport. It could be that composition and delegation is a better way to go.

确保您确实需要扩展 SqlMapClientDaoSupport。组合和授权可能是更好的方式。