Spring Autowiring仅适用于Interface

时间:2011-06-28 18:23:05

标签: java spring autowired

我对spring框架很陌生并遇到了以下问题。

我有一个界面ClassA,由ClassA1ClassA2分类实现。

我将以下bean定义添加到applicationContext.xml

<bean id="class1" class="com.abc.ClassA1" />
<bean id="class2" class="com.abc.ClassA2" />

我想将两个实现类自动装配如下。

@Autowired
private ClassA1 classA1;

@Autowired
private ClassA2 classA2;

以上代码将错误抛出

  

无法自动写入字段:com.abc.ClassA1 com.abc.SomeClass.classA1;嵌套异常是   org.springframework.beans.factory.NoSuchBeanDefinitionException:   没有匹配的bean类型   [com.abc.ClassA1]

但是,如果我将自动装配更改为接口,如下所示:

@Autowired
ClassA classA1;

然后ClassA1自动连接到变量。我对如何将变量自动装配到ClassA2感到无能为力。

5 个答案:

答案 0 :(得分:13)

出于某种原因,您的课程由Spring代理。有很多原因导致这种情况发生。例如,如果您使用JPA或AOP,则代理原始类。

如果类实现接口,则代理意味着动态代理。所以基本上在运行时创建一个新类来实现接口但不从原始类继承。因此,原始类的自动装配不起作用。

答案 1 :(得分:6)

如果您的对象由JDK代理代理,那么它们的接口应该引用它们。您可以使用CGLIB(在类路径上)和aop配置中的proxy-target-class="true"(在applicationContext.xml中)

通过具体类创建代理

答案 2 :(得分:3)

我尝试了多种方法来解决这个问题,但我按照以下方式运行。

@Autowired
private ClassA classA1;

@Autowired
private ClassA classA2;

在应用程序上下文中,我将bean定义如下:

<bean id="classA1" class="com.abc.ClassA1" autowire="byName" />
<bean id="classA2" class="com.abc.ClassA2" autowire="byName" />

答案 3 :(得分:1)

您可以使用@Qualifier注释:

@Autowired
@Qualifier("class1")
ClassA classA1;

@Autowired
@Qualifier("class2")
ClassA classA2;

参考:http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-autowired-annotation-qualifiers

@Resource注释:

@Resource(name="class1")
ClassA classA1;

@Resource(name="class2")
ClassA classA2;

参考:http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-resource-annotation

答案 4 :(得分:0)

我有自动化抽象服务的类似问题。您可以使用没有任何问题的代码:

@Autowired
@Qualifier("classA1")
private ClassA1 classA1;

@Autowired
@Qualifier("classA2")
private ClassA2 classA2;

只有在声明你的bean时才会这样做

<bean id="class1" class="com.abc.ClassA1" />

或者像这样

@Component("classA1")
public class ClassA1 {
...
}