当前位置: 首页 > 知识库问答 >
问题:

使用Spring向构造函数注入javax.inject.provider时的NoSuchBeanDefinitionException

梁俊智
2023-03-14
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);
    }

}

创建名为“Greeting Service”的bean时出错:通过构造函数实例化bean失败;嵌套异常是org.springframework.beans.BeanInstantiationException:未能实例化[GreetingService]:构造函数抛出异常;嵌套异常是org.springframework.beans.factory.NosuchBeanDefinitionException:没有找到用于依赖项的[java.lang.String]类型的合格bean:需要至少有1个bean作为此依赖项的autowire候选。依赖项批注:{}

共有1个答案

卢文博
2023-03-14

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

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

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

@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) {
...

要确切地说明要插入哪个提供程序实现。

 类似资料:
  • 和另一个类: 在这种情况下,服务将按照预期注入到A类中。据我所知,你不能在a类中使用构造函数,否则注入将无法工作。有没有一种方法可以在a类中使用一个构造函数,同时注入服务?即: 在这种情况下,我得到的服务是空的,无论如何要解决这个问题?我希望能够从类型A中使用“new”创建一个对象,并注入服务,这可能吗?

  • 请帮助理解在哪种情况下我应该使用构造函数注入和设置器注入。请帮我举个合适的例子。 先谢谢你。

  • 大家都知道@Autowired(@Inject etc)注释是由AutowiredAnnotationBeanPostProcessor处理的。它解析并设置用@Autowired注释的字段和setter,但构造函数呢?这是bean后处理器,这意味着它是在已经创建bean之后调用的,但是构造函数也可以标记为@Autowired,那么如何创建这样的bean呢?

  • 何时在Spring中使用构造函数注入? 我听说,当您在使用组件之前必须拥有依赖类的实例时,构造函数注入特别有用。但这意味着什么? 有没有人可以用一些简单的例子来解释我以下的时刻: 使用构造函数注入有什么好处

  • 我有一个父类,其中包含构造函数注入的依赖项: 如果我从这个类继承,我总是需要重新定义一个调用父构造函数的构造函数吗? 使用 setter 注入,我似乎能够将依赖项保留在父类中,而不需要在子类中重新连接它,如果子类不接触链接到依赖项的功能,这对我来说听起来不错: 看起来,如果我想避免重复自动装配代码和处理子组件中的依赖关系,我只能使用setter或field injection来实现。 是否有更简洁

  • 我想在构造函数中使用Request类,这是我想运行服务器时它给我的错误: 无法自动连接服务"AppBundle\Controller\DetectServiceDetailController":方法"__construct()"引用类"Symfony\Component\HttpFoundation\Request"的参数"$ask",但不存在这样的服务。它不能自动注册,因为它来自不同的根命名空