模糊的自动装配,但没有限定符

时间:2016-04-07 08:27:01

标签: java spring inversion-of-control

我有一项服务,其中Bean注入了@Autowired,如下所示。

@Service
public class AdminServiceImpl implements AdminService {
    @Autowired
    private WebServiceTemplate adminServiceTemplate;
}

一个包含两个bean的xml,导致模糊的自动装配

<bean id="serviceWebClient" class="org.springframework.ws.client.core.WebServiceTemplate" scope="prototype">
    <constructor-arg ref="messageFactory" />
    <property name="marshaller" ref="marshaller" />
<!-- More properties -->
</bean>

<bean id="adminServiceWebClient" class="org.springframework.ws.client.core.WebServiceTemplate" scope="prototype">
    <constructor-arg ref="messageFactory" />
    <property name="marshaller" ref="marshaller" />
<!-- More properties -->
</bean>

这显然会导致以下异常(启动时)

No qualifying bean of type [org.springframework.ws.client.core.WebServiceTemplate] is defined: expected single matching bean but found 2: serviceWebClient,adminServiceWebClient

奇怪的部分:

当我在我的服务中添加@Qualifier以指定要选择的Bean时,它突然找不到任何内容。例如。我将我的服务编辑为以下内容:

@Service
public class AdminServiceImpl implements AdminService {
    @Autowired
    @Qualifier("adminServiceWebClient")
    private WebServiceTemplate adminServiceTemplate;
}

而不是获取指定的Bean,我收到以下异常消息(稍后当我使用ApplicationContext 检索context = new ClassPathXmlApplicationContext(CONFIG_FILE);时:

 No qualifying bean of type [org.springframework.ws.client.core.WebServiceTemplate] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.

对这种奇怪的事情有什么合理的解释吗?我甚至不确定从哪里开始调试。它似乎找到了两者,但仍然拒绝autowire一个。

修改

从我的BeanXML注释中删除其他@Qualifier时,仍然获取:

 No qualifying bean of type [org.springframework.ws.client.core.WebServiceTemplate] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.

但它在启动时工作正常。它在调用后失败了:

context = new ClassPathXmlApplicationContext(CONFIG_FILE);

所以在启动时它似乎找到它(它是必需的并且不会失败),但是在请求上下文时它会失败。

2 个答案:

答案 0 :(得分:1)

也许您实际上是在启动两个应用程序上下文?一个人会让那些豆子出现,而另一个则不会。

如果是这种情况,当存在限定符时,第一个上下文将开始正常,但是由于缺少bean而导致第二个上下文失败(异常#2)。如果没有限定符,则由于两个替换项,第一个上下文将无法启动。

要解决此问题(在启动第二个上下文时),请为其提供父上下文:

new ClassPathXmlApplicationContext(new String[]{CONFIG_LOCATION}, parentContext);

答案 1 :(得分:0)

我发现了这个问题发生的原因。这是一个(相当愚蠢的)错误。如果其他人也遇到此问题,请查看以下内容:

概述

我使用各种Spring Bean文件运行我的应用程序。当我的应用程序启动时,我使用一个“主要上下文”文件,它执行我整个基本包的component-scan。在这个“主”文件中,我有WebServiceTemplate Beans

启动

我的component-scan找到我的service并自动将其尊重WebServiceTemplate Bean加入其中。所以它在启动时运行正常,正如预期的那样。

运行

当我打电话

context = new ClassPathXmlApplicationContext(CONFIG_FILE);

我实际上称之为不同的文件。此文件包含WebServiceTemplate Beans,但 还包含整个基本包的component-scan。导致它找到我的Service,但不是它应该自动装配的豆。

解决方案

加载其他文件时,我将component-scan更改为更加缩小到我需要的范围。因此它不会扫描服务,但会在启动时加载。