Edit: Perhaps a more concise way to ask this question is: Does Spring provide a way for me to resolve ambiguous candidates at injection time by providing my own listener/factory/decision logic?
In fact, arguably the @Environmental qualifier on the member field below is unnecessary: if an @Inject-ion is ambiguous... let me help? In fact, @ResolveWith(EnvironmentalResolver.class) would be alright too..
When Spring attempts to inject a dependency (using annotations) I understand that I need to @Qualifier an @Inject point if I am to have multiple components that implement that interface.
What I'd like to do is something like this:
class MyFoo implements Foo {
@Inject
@Environmental
private Bar bar;
}
@Environmental(Environment.Production)
class ProductionBar implements Bar {
}
@Environmental({Environment.Dev, Environment.Test})
class DevAndTestBar implements Bar {
}
I would expect that I need to create some kind of ambiguity resolver which would look something (vaguely) like this:
class EnvironmentalBeanAmbiguityResolver {
// set from configuration, read as a system environment variable, etc.
private Environment currentEnvironment;
public boolean canResolve(Object beanDefinition) {
// true if definition has the @Environmental annotation on it
}
public Object resolve(Collection<Object> beans) {
for (Object bean : beans) {
// return bean if bean @Environmental.values[] contains currentEnvironment
}
throw new RuntimeException(...);
}
}
One example of where this would be useful is we have a service that contacts end-users. Right now I just have a hacked together AOP aspect that before the method call to the "MailSender', checks for a "Production" environment flag and if it is not set, it sends the email to us instead of the users email. I'd like to instead of wrapping this in an AOP aspect specific to mail sending, instead be able to differentiate services based on the current environment. Sometime's it is just a matter of "production" or "not production" as I've demonstrated above, but a per-environment definition works too.
I think this can be reused for region too... e.g. @Regional and @Regional(Region.UnitedStates) and so on and so forth.
I'd imagine @Environmental would actually be a @Qualifier that way if you wanted to depend directly on something environmental you could (an @Environmental(Production) bean would likely depend directly on an @Environmental(Production) collaborator - so no ambiguity for lower level items --- same a @Regional(US) item would depend on other @Regional(US) items expiclitly and would bypass my yet-to-be-understood BeanAmbiguityResolver)
Thanks.