I\'m using Spring Beans with annotations and I need to choose different implementation at runtime.
@Service
public class MyService {
public void test(){..
Let's create beautiful config.
Imagine that we have Animal interface and we have Dog and Cat implementation. We want to write write:
@Autowired
Animal animal;
but which implementation should we return?
So what is solution? There are many ways to solve problem. I will write how to use @Qualifier and Custom Conditions together.
So First off all let's create our custom annotation:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE})
public @interface AnimalType {
String value() default "";
}
and config:
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class AnimalFactoryConfig {
@Bean(name = "AnimalBean")
@AnimalType("Dog")
@Conditional(AnimalCondition.class)
public Animal getDog() {
return new Dog();
}
@Bean(name = "AnimalBean")
@AnimalType("Cat")
@Conditional(AnimalCondition.class)
public Animal getCat() {
return new Cat();
}
}
Note our bean name is AnimalBean. why do we need this bean? because when we inject Animal interface we will write just @Qualifier("AnimalBean")
Also we crated custom annotation to pass the value to our custom Condition.
Now our conditions look like this (imagine that "Dog" name comes from config file or JVM parameter or...)
public class AnimalCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
if (annotatedTypeMetadata.isAnnotated(AnimalType.class.getCanonicalName())){
return annotatedTypeMetadata.getAnnotationAttributes(AnimalType.class.getCanonicalName())
.entrySet().stream().anyMatch(f -> f.getValue().equals("Dog"));
}
return false;
}
}
and finally injection:
@Qualifier("AnimalBean")
@Autowired
Animal animal;