我正在使用Spring 3.2.5,我正在尝试创建一个类实现BeanNameAware
。 如果没有实现此类,我的应用程序就可以运行。
当我实现它时,无法启动错误,如:
引起: org.springframework.beans.factory.NoSuchBeanDefinitionException:没有 找到类型为[mypackage.AccountSiebelDataHolder]的限定bean 依赖:预计至少有1个bean有资格成为autowire 这种依赖的候选人。依赖注释: {@ org.springframework.beans.factory.annotation.Qualifier(值= accountSiebelDataHolder), @ org.springframework.beans.factory.annotation.Autowired(所需=真)}
我有这样的classe:
@Transactional
public abstract class DataHolder<T extends DbObject> implements BeanNameAware{
private String beanName;
...
@Override
public void setBeanName(String name) {
System.out.println(name);
this.beanName=name;
}
}
有几个课程扩展了这门课程:
public class AccountSiebelDataHolder extends DataHolder<AccountSiebel> {
...
}
bean是在xml:
中创建的<bean id="accountSiebelDataHolder" class="mypackage.AccountSiebelDataHolder">
...
</bean>
我知道我的豆子很好,因为我在控制台中看到每个豆子的名字。
调用setBeanName()
方法。
但在此之后,它在自动装配时失败(有或没有@Qualifier
相同)
我在childs类中尝试了实现BeanNameAware
,它给了我相同的结果。
也许这很重要:这些Dataholder
类由Spring根上下文实例化。然后注入@Controller
bean,这些bean在@MVC上下文中实例化。但它在BeanNameAware
之后效果很好。
答案 0 :(得分:3)
问题出现在@Transactional
。使用AOP应用事务,默认情况下Spring uses proxies应用AOP。
如果没有接口,spring将使用cglib创建基于类的代理。在运行时,会创建一个动态子类,此子类仍然是DataHolder
实例。
添加接口将导致创建JDK动态代理,即接口。在运行时,创建动态类,实现对象的所有接口以进行代理。这导致类成为BeanNameAware
实例,而不再是DataHolder
的实例。
要解决此问题,请求您的事务支持始终使用基于类的代理。为此,将proxy-target-class
上的<tx:annoation-driven />
属性设置为true
。
<tx:annotation-driven proxy-target-class="true" />