gst*_*low 12 java spring autowired spring-boot
我有以下配置:
@Qualifier1
@Qualifier2
@Bean
public MyBean bean1(){...}
@Qualifier2
@Qualifier3
@Bean
public MyBean bean2(){...}
@Qualifier1
@Qualifier2
@Qualifier3
@Bean
public MyBean bean3(){...}
@Qualifier3
@Bean
public MyBean bean4(){...}
@Qualifier1
@Bean
public MyBean bean5(){...}
Run Code Online (Sandbox Code Playgroud)
这是注射的地方:
@Qualifier2
@Qualifier3
@Autowired:
private List<MyBean> beans;
Run Code Online (Sandbox Code Playgroud)
默认情况下,spring AND对每个逻辑使用逻辑@Qualifier
因此bean2,bean3将被注入。
但我想有OR逻辑的东西,所以我希望豆类bean1 bean2 bean3和bean4被注入
我该如何实现?
@Qualifier 注释不可重复,因此我必须为每个注释创建元注释:
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Qualifier1 {
}
Run Code Online (Sandbox Code Playgroud)
如果您使用标记接口而不是限定符怎么办?例如:
public class MyBean1 extends MyBean implements Marker1 {}
public class MyBean2 extends MyBean implements Marker2 {}
public class MyBean12 extends MyBean implements Marker1, Marker2 {}
Run Code Online (Sandbox Code Playgroud)
然后使用这个:
@Bean
public MyBean1 myBean1() {
//...
}
@Bean
public MyBean2 myBean2() {
//...
}
@Bean
public MyBean12 myBean12() {
//...
}
Run Code Online (Sandbox Code Playgroud)
和这个:
@Autowired private List<Marker1> myBeans;
Run Code Online (Sandbox Code Playgroud)
你会得到的名单myBean1和myBean12豆类。
为此:
@Autowired private List<Marker2> myBeans;
Run Code Online (Sandbox Code Playgroud)
你会得到的名单myBean2和myBean12豆类。
这样行吗?
更新我
自定义FactoryBean
我实现了TagsFactoryBean类和@Tags批注,您可以使用它们来解决您的任务(我希望:))。
首先,用@Tags注释标记您的bean :
@Tags({"greeting", "2letters"})
@Bean
public Supplier<String> hi() {
return () -> "hi";
}
@Tags({"parting", "2letters"})
@Bean
public Supplier<String> by() {
return () -> "by";
}
@Tags("greeting")
@Bean
public Supplier<String> hello() {
return () -> "hello";
}
@Tags("parting")
@Bean
public Supplier<String> goodbye() {
return () -> "goodbye";
}
@Tags("other")
@Bean
public Supplier<String> other() {
return () -> "other";
}
Run Code Online (Sandbox Code Playgroud)
然后准备TagsFactoryBean:
@Bean
public TagsFactoryBean words() {
return TagsFactoryBean.<Supplier>builder()
.tags("greeting", "other")
.type(Supplier.class)
.generics(String.class)
.build();
}
Run Code Online (Sandbox Code Playgroud)
这tags是需要选择其bean的所需标签的数组,type是所选bean的类型,并且generics是bean 的通用类型的数组。最后一个参数是可选的,仅当您的bean是通用的时才应使用。
然后可以将其与@Qualifier注释一起使用(否则,Spring会注入所有Supplier<String>类型的bean ):
@Autowired
@Qualifier("words")
private Map<String, Supplier<String>> beans;
Run Code Online (Sandbox Code Playgroud)
该地图beans将包含三个豆类:hi,hello和other(他们的名字是地图的钥匙,它们的实例是它的值)。
您可以在测试中找到更多用法示例。
更新二
自定义AutowireCandidateResolver
感谢@bhosleviraj的推荐,我实现了TaggedAutowireCandidateResolver,它简化了自动装配所需bean的过程。只需使用相同的标记标记您的bean和自动装配的集合,即可将它们注入到集合中:
@Autowired
@Tags({"greeting", "other"})
private Map<String, Supplier<String>> greetingOrOther;
@Configuration
static class Beans {
@Tags({"greeting", "2symbols", "even"})
@Bean
public Supplier<String> hi() {
return () -> "hi";
}
@Tags({"parting", "2symbols", "even"})
@Bean
public Supplier<String> by() {
return () -> "by";
}
@Tags({"greeting", "5symbols", "odd"})
@Bean
public Supplier<String> hello() {
return () -> "hello";
}
@Tags({"parting", "7symbols", "odd"})
@Bean
public Supplier<String> goodbye() {
return () -> "goodbye";
}
@Tags({"other", "5symbols", "odd"})
@Bean
public Supplier<String> other() {
return () -> "other";
}
}
Run Code Online (Sandbox Code Playgroud)
您不仅可以使用Map来注入bean,还可以使用其他Collections。
为了使其工作,您必须CustomAutowireConfigurer在应用程序中注册一个bean并为其提供TaggedAutowireCandidateResolver:
@Configuration
public class AutowireConfig {
@Bean
public CustomAutowireConfigurer autowireConfigurer(DefaultListableBeanFactory beanFactory) {
CustomAutowireConfigurer configurer = new CustomAutowireConfigurer();
beanFactory.setAutowireCandidateResolver(new TaggedAutowireCandidateResolver());
configurer.postProcessBeanFactory(beanFactory);
return configurer;
}
}
Run Code Online (Sandbox Code Playgroud)
有关更多用法示例,请参见此测试。
| 归档时间: |
|
| 查看次数: |
403 次 |
| 最近记录: |