Reputation: 1358
I have below annotation.
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Import(MyBeanInitializer.class)
public @interface MyAnnotation {
String clientType() default "" ;
}
And I have a Bean initialiser component as below
@Configuration
public class MyBeanInitializer {
@Bean() // trigger this when annoattion's value == "A"
public CommonBean firstBean() {
return new BeanA;
}
@Bean() // trigger this when annoattion's value == "B"
public CommonBean firstBean() {
return new BeanB;
}
}
My Commoin interface for BeanA and BeanB
public interface CommonBean {
void doSomething();
}
And my Two Implementations are
@Component()
public class BeanA implements CommonBean {
@Overrid
public void doSomething (){
// implementation here
}
}
@Component()
public class BeanB implements CommonBean {
@Overrid
public void doSomething (){
// implementation here
}
}
I need to use above as an library for another Spring Boot project. In that project I annotate Application.java
with @MyAnnotation(clientType="web")
and then I inject BeanA or BeanB to a class inside that project by using constructor Injection.
What is the mechanism to initialise beans by looking at the values passed through the annotation?
Upvotes: 1
Views: 1077
Reputation: 106400
Don't use an annotation value for this.
Annotation values are hard-coded at compile time and cannot be dynamically changed. Plus, it would look and feel incredibly awkward in the face of @Conditional
, which already exists and ties into the ability to get dynamic properties.
What you want to do is use either a combination of @Conditional
which allows you to define what you want to do given a specific environment variable, or use the @ConditionalOnProperty
annotation found in Spring Boot to simply provide the ability to wire in a bean based on the presence of a specific value in a specific property.
Here's how that'd look. Let's assume that you have properties called common.basicImpl
and common.advancedImpl
.
@Component
@ConditionalOnProperty(prefix = "common", value = "basicImpl")
public class BeanA implements CommonBean {
@Override
public void doSomething (){
// implementation here
}
}
@Component
@ConditionalOnProperty(prefix = "common", value = "advancedImpl")
public class BeanB implements CommonBean {
@Override
public void doSomething (){
// implementation here
}
}
Note that this alone wouldn't resolve a circumstance in which both properties were present, and you can't do multiple @ConditionalOnProperty
statements. Adding @ConditionalOnMissingBean
to be sure you don't accidentally wire up both of them at the same time would help you out there.
Upvotes: 2