Reputation: 2843
Let's assume I have an annotated bean property setter like this:
public class Foo {
...
@Autowired
public void setBar(Bar bar) {
...
}
The Springframework will lookup the matching Bar
property as usual. However, I'd like to intercept the default bean resolving process and add a little bit of "magic" myself. I'd like to introduce a resolver like this:
public interface SomeResolverInterface<T> {
public T resolve(Class<T> beanClass);
}
public class BarResolver implements SomeResolverInterface<Bar> {
@Override
public Bar resolve(Class<Bar> beanClass) {
if(someCondition) {
return someBean;
} else {
return anotherBean;
}
}
...
I know I could alway introduce some kind of wrapper bean and move the resolving logic into this but I'd prefer a more generic way using a resolver like described above to make Foo
completely independent of the resolving logic.
Is there a way within the Springframework to achieve something like this?
Upvotes: 3
Views: 250
Reputation: 597124
Apart from the @Configuration
option provided by Tomasz, you can use a simple FactoryBean
. Just implement the interface, and declare the factory bean. In the getObject()
method perform your custom logic.
Upvotes: 2
Reputation: 340763
From your description it looks like you only need to perform additional logic at startup time (autowiring). There are several ways to tackle this problem (from worst to best):
AOP - bad idea, introduces runtime overhead by intercepting every call
custom scope - see: Custom spring scopes? Also works at runtime and also a bad idea
@Profile
- define two matching beans and enable only one based on active profile. Pretty clean and introduces overhead only at startup time
@Configuration
- defining beans in Java has an extra benefit of having full control over how are they created:
@Configuration
public class Config {
@Autowired
private Bar someBean;
@Autowired
private Bar anotherBean;
@Bean
@Primary
public Bar primaryBean() {
if(someCondition) {
return someBean;
} else {
return anotherBean;
}
}
}
As you can see in this case we have three beans of Bar
type: someBean
, anotherBean
and primaryBean
. The first two can also be configured using @Bean
or via component scan with @Service
. But to make autowiring possible the last primaryBean
is marked as @Primary
. This way it will be preferred over other two.
This is my recommended solution as the resolving logic is clean, maintainable and readable. IMHO this is the situation where Java-based @Configuration
really shines.
Upvotes: 4
Reputation: 8169
Although I have never tried this I think you could look at plugging your logic via
AnnotationConfigUtils
Or look at
AutowiredAnnotationBeanPostProcessor
and see if it allows for simple extension/pluggability of your logic
Upvotes: 0