有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

@Bean方法的JavaSpring5自定义限定符NoSuchBeanDefinitionException

我一直在努力使用自定义@Qualifier和@Bean而不是工厂方法。看起来是这样的:

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, 
ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface MyCustomQualifierUno {
    String value() default "";
}

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, 
ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface MyCustomQualifierDos {
    String value() default "";
}

所需bean的工厂类由以下两种方法组成:

@Bean
@MyCustomQualifierUno
public RestTemplate getRestTemplate(SomeConfigUno config,
    SomeErrorHandlerUno errorHandler) {
        return new RestTemplateBuilder()
            (...)
            .build();
}

@Bean
@MyCustomQualifierDos
public RestTemplate getRestTemplate(SomeConfigDos config,
    SomeErrorHandlerDos errorHandler) {
        return new RestTemplateBuilder()
            (...)
            .build();
}

接下来,在客户机类中,我有一个如下的ctor注入:

public SomeClientUno(@SomeQualifierUno RestTemplate 
    restTemplate) {
        this.restTemplate = restTemplate;
}

public SomeClientDos(@SomeQualifierDos RestTemplate 
    restTemplate) {
        this.restTemplate = restTemplate;
}

当我尝试运行应用程序时,我得到: NoSuchBeanDefinitionException

非常有趣的事实是,当我添加一个专用的类来扩展REST模板并放置在这里,我的CuxQualEnter我得到异常时,现在实际上有两个bean(即现在它确实考虑了@ bean方法)!p>

贯穿:IntelliJ Ultimate 2019.1 操作系统:Windows 10 64位 Java:1.8.0_191 Spring版本:5.1.9

附言:那些“Uno”和“Dos”是为了强调一个事实,那就是它们是一些具体的类型,非常不相关,但不要与@Qualifiers中的“Uno”和“Dos”混淆


共 (1) 个答案

  1. # 1 楼答案

    这似乎太明显了,但为什么要使用限定符呢? 假设您这样定义bean:

    @Bean
    public RestTemplate restTemplateUno(...) { ... }
    
    @Bean
    public RestTemplate restTemplateDos(...) { ... }
    

    这将使用限定符“restemplateuno”和“restemplatedos”注册bean,因为“默认情况下,bean名称将与方法名称相同”(有关详细信息,请参见Spring Docs

    现在,您可以像这样将它们注入客户端构造函数:

    @Autowired
    public SomeClientUno(RestTemplate restTemplateUno) {...}
    
    @Autowired
    public SomeClientDos(RestTemplate restTemplateDos) {...}
    
    <>我希望这有帮助,我没有错过一些显而易见的事情,让你首先考虑使用限定词。