1

我正在使用基于构造函数的依赖注入将 a 注入javax.inject.Provider<T>到服务中。使用 Spring Framework (4.2.5),NoSuchBeanDefinitionException将抛出“没有找到类型为 [T] 的合格 bean 的依赖项。为什么TSpring 在注入时会期望javax.inject.Provider<T>

这是示例代码:

提供者:

import javax.inject.Provider;

public class MessageProvider implements Provider<String> {

    @Override
    public String get() {
        return "Hello!";
    }

}

服务:

import javax.inject.Inject;
import javax.inject.Provider;

public class GreetingService {

    private final String message;

    @Inject
    GreetingService(Provider<String> provider) {
//     GreetingService(MessageProvider provider) { // this works!
        this.message = provider.get();
    }

    public String greeting() {
        return message;
    }

}

测试:

import org.junit.Test;
import static org.junit.Assert.*;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class GreetingServiceTest {

    @Test
    public void testSomeMethod() {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
        ctx.register(MessageProvider.class);
        ctx.register(GreetingService.class);
        ctx.refresh();

        GreetingService bean = ctx.getBean(GreetingService.class);
        String message = bean.greeting();

        assertNotNull(message);
    }

}

这是错误消息:

创建名为“greetingService”的 bean 时出错:通过构造函数实例化 bean 失败;嵌套异常是 org.springframework.beans.BeanInstantiationException: 无法实例化 [GreetingService]: 构造函数抛出异常;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type of [java.lang.String] found for dependency: 预计至少有 1 个 bean 有资格作为此依赖项的自动装配候选者。依赖注释:{}

4

1 回答 1

0

你的问题有点模棱两可。您是在问为什么 Spring 需要一个可以创建 a 的 bean,T还是在问为什么 Spring 不注入您的MessageProvider类的实例?

如果您的问题是前者,那么您面临的问题Provider<T>是接口,而不是类。当你注入Provider<String>Spring 时说,“嗯,我没有看到任何Provider接口的 bean 定义,有没有另一种方法可以满足这种依赖关系?” 而 Spring 的回答是,“是的,我可以创建 的实例org.springframework.beans.support.DefaultListableBeanFactory$DependencyProvider,但前提是我知道如何创建T,即存在 的 bean 定义T。”

如果您添加了一个配置类来定义一个类型的 bean,您的示例代码应该可以工作String

@Configuration
public class MyConfiguration
{
    @Bean
    public String getMessage()
    {
        return "Hello!";
    }
}

但是,如果您问为什么 Spring 没有注入您的MessageProvider类的实例,我怀疑问题在于它没有正确定义。您可以在MessageProvider定义和用法中添加限定符

@Component("MyMessageProvider")
public class MessageProvider implements Provider<String> {
...

@Inject
GreetingService(@Qualifier("MyMessageProvider") Provider<String> provider) {
...

准确地说出Provider您要注入的实现。

于 2017-02-17T20:04:22.490 回答