I have a HsqldbReconciler (for "work" with a HSQLDB database) which I autowired, like:
@Autowired
HsqldbReconciler hsqldbReconciler;
In Future there will be a OracleReconciler, MssqlReconciler, etc. I will need to use them accordingly to the type of connection a user has chosen.
How should I implement this? Usually I would have a kind of factory, which returns only the needed Reconciler. The only way in spring, I can currently imagine, is to Autowire an instance of each Reconciler, then use one of them in the code. Is there a better way?
You can use @Autowired(required=false) and null check in stopScheduler method.
It's used to indicate whether a given component is eligible for registration based on a defined condition.
The difference are that @Autowired and @Qualifier are the spring annotation while @Resource is the standard java annotation (from JSR-250) . Besides , @Resource only supports for fields and setter injection while @Autowired supports fields , setter ,constructors and multi-argument methods injection.
If we had used Autowired, we would have been getting the following error in the test. Therefore, it is not recommended to use Autowired. Safety — Forces Spring to provide mandatory dependencies. We make sure that the created objects are valid after construction.
make a Factory Class that will contain all your beans, e.g
@Component
class Factory{
@Autowired HsqldbReconciler hsqldb;
@Autowired OracleReconciler oracle;
@Autowired MssqlReconciler mssql;
public Object getInstance(String type){
switch(type){
case "mssql" : return mssql;
case "oracle" : return oracle;
// and so on
default : return null;
}
}
}
Now use this Factory as follows
class SomeClass{
@Autowired private Factory factory;
public Object someMethod(){
Object reconciler = factory.getInstance("mssql");
((MssqlReconciler)reconciler).someMethod();
}
}
Define them in your Config with the same name, but different conditions:
@Bean(name = "dbReconciler")
@Conditional(HsqldbReconcilerEnabled.class)
public ReconcilerBase getHsqldbReconciler() {
return new HsqldbReconciler();
}
@Bean(name = "dbReconciler")
@Conditional(OracleReconcilerEnabled.class)
public ReconcilerBase getOracleReconciler() {
return new OracleReconciler();
}
@Bean(name = "dbReconciler")
@Conditional(MssqlReconcilerEnabled.class)
public ReconcilerBase getMssqlReconciler() {
return new MssqlReconciler();
}
create conditions reading from app.properties:
HsqldbReconciler.enabled=true
OracleReconciler.enabled=false
MssqlReconciler.enabled=false
like this:
public class HsqldbReconcilerEnabled implements Condition {
private static final String PROP_ENABLED = "HsqldbReconciler.enabled";
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String property = context.getEnvironment().getProperty(PROP_ENABLED);
return Boolean.parseBoolean(property);
}
}
// etc...
use like:
@Autowired
@Qualifier("dbReconciler")
ReconcilerBase dbReconsiler;
ensure you're not enabling multiple beans at the same time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With