请教:Spring @Autowired注解实现了接口的成员变量时失败

yu1ei 2011-07-21 10:57:10
场景:
1、类A中有成员变量类B,类B使用@Autowired注解的方式注入A中。
2、类B实现了接口IB.

问题:
启动时报错:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'a':
Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: com.siqisoft.test.B com.siqisoft.test.A.b;
nested exception is java.lang.IllegalArgumentException:
Can not set com.siqisoft.test.B field com.siqisoft.test.A.b to $Proxy23

疑问:
为什么实现了接口的B不能被注入到A中呢?

类A:

package com.siqisoft.test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class A {
@Autowired
B b;
}


类B:

package com.siqisoft.test;

import org.springframework.stereotype.Component;

@Component
public class B {
public void BMethod(){};
}

B实现的接口

package com.siqisoft.test;

public abstract interface IB {

}

...全文
80481 24 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
zzc_q 2013-11-18
  • 打赏
  • 举报
回复
接口类的实现类定义前加上@Service
gty3d987321 2013-11-14
  • 打赏
  • 举报
回复
试试在你action里调用过的所有注入接口实现类里面加上@component 试试
caibin_caibin 2013-10-22
  • 打赏
  • 举报
回复
引用 19 楼 zl3450341 的回复:
我也不知道你的具体开发环境是怎么样的。 @Autowired是自对注入么,你写好了接口,他会自动去找他的实现,如果有多个实现他就依赖于@Qualifier @Resource是直接指定名子的,当然了。
其实这位大神说的没错,有可能是你的配置文件出了问题,我的就是直接注入接口就ok了,但是!!!!但是!!!我单独做个springMVC的例子时尽然没成功!!那个郁闷。。。
百度2030 2013-09-06
  • 打赏
  • 举报
回复
有没有配置文件信息,贴出来看看,我怀疑是配置文件的问题
zeroren 2012-06-30
  • 打赏
  • 举报
回复
需要在xml加下bean
老张-AI 2011-07-21
  • 打赏
  • 举报
回复
楼主问题解决了没有?
老张-AI 2011-07-21
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 wcnqrm 的回复:]

接口为什么要定义成抽象的呢~
[/Quote]

接口本身就是最高层次的抽象,所以用不用abstract 在语法上都是可以的
老张-AI 2011-07-21
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 yu1ei 的回复:]

哎呀!还是不行,因为IB中没有我在A类中想调用的方法BMethod。。。。
[/Quote]

那你就别让B 实际IB接口。。直接用B来注入。

或者,你在IB接口中添加一个BMethod。
wcnqrm 2011-07-21
  • 打赏
  • 举报
回复
接口为什么要定义成抽象的呢~
yu1ei 2011-07-21
  • 打赏
  • 举报
回复
哎呀!还是不行,因为IB中没有我在A类中想调用的方法BMethod。。。。
老张-AI 2011-07-21
  • 打赏
  • 举报
回复
问题解决了就好。记得结账
yu1ei 2011-07-21
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 zl3450341 的回复:]

Error creating bean with name 'a':

又那里来的a列?

关于你的思考,回答如下:

@Autowired
@Qualifier("b") //用B类型去注入. 请注意类名首字母小写
private BI b
[/Quote]

解释
我的A上注释了:@Component。让Spring启动时,扫描到这是一个组件,然后自动实例化它,实例化a的时候,发现它有个成员变量b要注入,又去忙活找b,找b的时候,就出现问题了。。。。

尝试
你的方法我用了,A类的成员变量改为IB接口,然后注解为@Qualifier("b"),成功启动。

我转移到正式的代码中试试。

老张-AI 2011-07-21
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 zn85600301 的回复:]

引用 2 楼 yu1ei 的回复:

整个错误堆栈
Java code

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'a': Injection of autowired dependencies failed; nested exception is o……

Caused by: java.lang.IllegalArgumentException: Can not set com.siqisoft.test.B field com.siqisoft.test.A.b to $Proxy23
没有set 方法
[/Quote]

@Autowired 是不需要set方法的
yu1ei 2011-07-21
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 zn85600301 的回复:]

引用 2 楼 yu1ei 的回复:

整个错误堆栈
Java code

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'a': Injection of autowired dependencies failed; nested exception is o……
[/Quote]

验证

加了Set方法了,仍旧不好用。

思考
其实,及时没有set方法的private字段,Spring还是有很多手段给它设值的,这个不是导致问题的原因
老张-AI 2011-07-21
  • 打赏
  • 举报
回复
Error creating bean with name 'a':

又那里来的a列?

关于你的思考,回答如下:

@Autowired
@Qualifier("b") //用B类型去注入. 请注意类名首字母小写
private BI b
zn85600301 2011-07-21
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 yu1ei 的回复:]

整个错误堆栈
Java code

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'a': Injection of autowired dependencies failed; nested exception is org.springframework.bea……
[/Quote]
Caused by: java.lang.IllegalArgumentException: Can not set com.siqisoft.test.B field com.siqisoft.test.A.b to $Proxy23
没有set 方法
yu1ei 2011-07-21
  • 打赏
  • 举报
回复
尝试
把B b; 改成IB b试试
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'a':
Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field: com.siqisoft.test.IB com.siqisoft.test.A.b;
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No matching bean of type [com.siqisoft.test.IB] found for dependency:
expected at least 1 bean which qualifies as autowire candidate for this dependency.
Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

思考
这个做法报了如上面的错误。
考虑一下:如果整个工程有多个类实现了IB接口,那么A想使用哪个IB该如何决定呢?所以写成IB应该是不对的。
而且IB里没有我要调用的方法,我要调用B类中的方法。只是很不幸,B必须要实现IB。

原始模型
其实B类是实现了一个ApplicationListener接口来响应事件的一个类。B类中设置了一块List成员变量缓存所有发生的事件,我的A类有时需要请求这个B类来获得已发生的事件列表,所以想把B类Autowired进A类中。
老张-AI 2011-07-21
  • 打赏
  • 举报
回复
貌似@autowired 是注入接口的吧。

你把B b; 改成IB b试试
我嘞个去 2011-07-21
  • 打赏
  • 举报
回复
yu1ei 2011-07-21
  • 打赏
  • 举报
回复
整个错误堆栈

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'a': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.siqisoft.test.B com.siqisoft.test.A.b; nested exception is java.lang.IllegalArgumentException: Can not set com.siqisoft.test.B field com.siqisoft.test.A.b to $Proxy23
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:276)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:197)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4135)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4630)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:785)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:445)
at org.apache.catalina.core.StandardService.start(StandardService.java:519)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
at org.apache.catalina.startup.Catalina.start(Catalina.java:581)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.siqisoft.test.B com.siqisoft.test.A.b; nested exception is java.lang.IllegalArgumentException: Can not set com.siqisoft.test.B field com.siqisoft.test.A.b to $Proxy23
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:502)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:282)
... 28 more
Caused by: java.lang.IllegalArgumentException: Can not set com.siqisoft.test.B field com.siqisoft.test.A.b to $Proxy23
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(Unknown Source)
at java.lang.reflect.Field.set(Unknown Source)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:498)
... 30 more
加载更多回复(3)

67,549

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧