如果您使用标记接口而不是限定符会怎样?例如:
public class MyBean1 extends MyBean implements Marker1 {}
public class MyBean2 extends MyBean implements Marker2 {}
public class MyBean12 extends MyBean implements Marker1, Marker2 {}
然后使用这个:
@Bean
public MyBean1 myBean1() {
//...
}
@Bean
public MyBean2 myBean2() {
//...
}
@Bean
public MyBean12 myBean12() {
//...
}
还有这个:
@Autowired private List<Marker1> myBeans;
您将获得myBean1 和myBean12 bean 的列表。
为此:
@Autowired private List<Marker2> myBeans;
您将获得myBean2 和myBean12 bean 的列表。
这行得通吗?
更新我
自定义 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";
}
那就准备TagsFactoryBean:
@Bean
public TagsFactoryBean words() {
return TagsFactoryBean.<Supplier>builder()
.tags("greeting", "other")
.type(Supplier.class)
.generics(String.class)
.build();
}
这里tags 是一组应选择的bean 的期望标签,type 是一个选定的bean 类型,generics 是一组泛型类型的bean。最后一个参数是可选的,仅当您的 bean 是通用的时才应使用。
然后你可以将它与@Qualifier注解一起使用(否则Spring会注入所有Supplier<String>类型的bean):
@Autowired
@Qualifier("words")
private Map<String, Supplier<String>> beans;
Map beans 将包含三个 bean:hi、hello 和 other(它们的名称是 Map 的键,它们的实例是它的值)。
您可以在tests 中找到更多使用示例。
更新 II
自定义 AutowireCandidateResolver
感谢@bhosleviraj recommendation,我实现了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";
}
}
您不仅可以使用 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;
}
}
更多用法示例见Test。