Spring 5 - @Bean 方法的自定义限定符 - NoSuchBeanDefinitionException
Spring 5 - custom qualifiers for @Bean methods - 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 的工厂class 由以下两种方法组成:
@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();
}
接下来,在客户端 class 我有一个这样的 ctor 注入:
public SomeClientUno(@SomeQualifierUno RestTemplate
restTemplate) {
this.restTemplate = restTemplate;
}
public SomeClientDos(@SomeQualifierDos RestTemplate
restTemplate) {
this.restTemplate = restTemplate;
}
当我尝试 运行 我得到的应用程序:
NoSuchBeanDefinitionException
非常有趣的事实是,当我添加一个扩展 RestTemplate 的专用 class 并将我的 @CustomQualifier 放在那里时,我得到异常,现在实际上有两个 bean(即现在它确实考虑@Bean 方法)!
运行 通过:IntelliJ Ultimate 2019.1
OS: Windows 10 64 位
Java: 1.8.0_191
Spring版本:5.1.9
PS。 @Qualifiers
中的 "Uno's and 'Dos'ses are meant to stress the fact, that those are some concrete types, quite irrelevant, but don't get confused with the "Uno 和“Dos”
这似乎太明显了,但为什么要使用限定词呢?
假设您这样定义 bean:
@Bean
public RestTemplate restTemplateUno(...) { ... }
@Bean
public RestTemplate restTemplateDos(...) { ... }
这会使用限定符 "restTemplateUno" 和 "restTemplateDos" 注册 bean,因为 "By default, the bean name will be the same as the method name"(有关详细信息,请参阅 Spring Docs)。
您现在可以像这样将它们注入到客户端构造函数中:
@Autowired
public SomeClientUno(RestTemplate restTemplateUno) {...}
@Autowired
public SomeClientDos(RestTemplate restTemplateDos) {...}
希望这对您有所帮助,并且我没有遗漏任何明显的问题,这些问题让您首先考虑使用限定符。
我一直在努力通过工厂方法将自定义@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 的工厂class 由以下两种方法组成:
@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();
}
接下来,在客户端 class 我有一个这样的 ctor 注入:
public SomeClientUno(@SomeQualifierUno RestTemplate
restTemplate) {
this.restTemplate = restTemplate;
}
public SomeClientDos(@SomeQualifierDos RestTemplate
restTemplate) {
this.restTemplate = restTemplate;
}
当我尝试 运行 我得到的应用程序: NoSuchBeanDefinitionException
非常有趣的事实是,当我添加一个扩展 RestTemplate 的专用 class 并将我的 @CustomQualifier 放在那里时,我得到异常,现在实际上有两个 bean(即现在它确实考虑@Bean 方法)!
运行 通过:IntelliJ Ultimate 2019.1 OS: Windows 10 64 位 Java: 1.8.0_191 Spring版本:5.1.9
PS。 @Qualifiers
中的 "Uno's and 'Dos'ses are meant to stress the fact, that those are some concrete types, quite irrelevant, but don't get confused with the "Uno 和“Dos”这似乎太明显了,但为什么要使用限定词呢? 假设您这样定义 bean:
@Bean
public RestTemplate restTemplateUno(...) { ... }
@Bean
public RestTemplate restTemplateDos(...) { ... }
这会使用限定符 "restTemplateUno" 和 "restTemplateDos" 注册 bean,因为 "By default, the bean name will be the same as the method name"(有关详细信息,请参阅 Spring Docs)。
您现在可以像这样将它们注入到客户端构造函数中:
@Autowired
public SomeClientUno(RestTemplate restTemplateUno) {...}
@Autowired
public SomeClientDos(RestTemplate restTemplateDos) {...}
希望这对您有所帮助,并且我没有遗漏任何明显的问题,这些问题让您首先考虑使用限定符。