He siguiente configuración:
@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(){...}
Y es el lugar de inyección:
@Qualifier2
@Qualifier3
@Autowired:
private List<MyBean> beans;
Por defecto primavera utiliza AND
la lógica para cada@Qualifier
Así bean2
y bean3
será inyectado.
Pero yo quiero tener OR
la lógica de esas cosas por lo que espero habas bean1
bean2
bean3
y bean4
para ser inyectado
¿Cómo puedo lograrlo?
PD
@Qualifier
anotación no es repetible, así que tengo para crear anotaciones meta para cada anotación:
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Qualifier1 {
}
Lo que si se ha utilizado interfaces de marcadores en vez de eliminatorias? Por ejemplo:
public class MyBean1 extends MyBean implements Marker1 {}
public class MyBean2 extends MyBean implements Marker2 {}
public class MyBean12 extends MyBean implements Marker1, Marker2 {}
Luego, utilizando la siguiente:
@Bean
public MyBean1 myBean1() {
//...
}
@Bean
public MyBean2 myBean2() {
//...
}
@Bean
public MyBean12 myBean12() {
//...
}
y esto:
@Autowired private List<Marker1> myBeans;
Se podría obtener una lista de myBean1
y myBean12
frijoles.
Y para esto:
@Autowired private List<Marker2> myBeans;
Se podría obtener una lista de myBean2
y myBean12
frijoles.
esto funcionara?
ACTUALIZACIÓN I
FactoryBean personalizada
He implementado TagsFactoryBean clase y @Tags anotación que se puede utilizar para resolver su tarea (espero :)).
En primer lugar, marcar sus granos con @Tags
anotación:
@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";
}
A continuación, preparar TagsFactoryBean
:
@Bean
public TagsFactoryBean words() {
return TagsFactoryBean.<Supplier>builder()
.tags("greeting", "other")
.type(Supplier.class)
.generics(String.class)
.build();
}
Aquí tags
es un conjunto de etiquetas deseadas cuyos granos deben ser seleccionados, type
es un tipo de granos seleccionados, y generics
una gran variedad de tipos genéricos de los granos. El último parámetro es opcional y sólo debe utilizarse si sus granos son genéricos.
A continuación, puede utilizarlo con @Qualifier
la anotación (de lo contrario primavera inyecta todos los granos de Supplier<String>
tipo):
@Autowired
@Qualifier("words")
private Map<String, Supplier<String>> beans;
El Mapa beans
contendrá tres granos: hi
, hello
y other
(su nombre son las claves del mapa y sus casos son sus valores).
Más ejemplos de uso se pueden encontrar en las pruebas .
ACTUALIZACIÓN II
AutowireCandidateResolver personalizada
Gracias a @bhosleviraj recomendación , que implementan TaggedAutowireCandidateResolver que simplifica el proceso de Autowiring los granos deseados. Simplemente marque sus frijoles y la colección autowired con las mismas etiquetas y obtendrá las inyectaron en la colección:
@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";
}
}
Puede usar no sólo el mapa de inyección de granos, sino también a otras colecciones.
Para que funcione hay que registrarse un CustomAutowireConfigurer
frijol en su aplicación y dotarla de TaggedAutowireCandidateResolver
:
@Configuration
public class AutowireConfig {
@Bean
public CustomAutowireConfigurer autowireConfigurer(DefaultListableBeanFactory beanFactory) {
CustomAutowireConfigurer configurer = new CustomAutowireConfigurer();
beanFactory.setAutowireCandidateResolver(new TaggedAutowireCandidateResolver());
configurer.postProcessBeanFactory(beanFactory);
return configurer;
}
}
Más ejemplos de uso ver en esta prueba .