In Spring, is there a mechanism or listener to detect when a bean annotated with a specific annotation is getting @Autowired
and run some custom logic on it? Something similar to what @ConfigurationProperties
already does that automatically injects fields before it gets autowired.
I have a requirement in which I need to inject values to fields of certain beans annotated with @ExampleAnnotation
before they get instantiated. Ideally, in this listener, I would:
@ExampleAnnotation
Is something like this possible?
You can achive it with the following code:
@Component
class MyBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// Every spring bean will visit here
// Check for superclasses or interfaces
if (bean instanceof MyBean) {
// do your custom logic here
bean.setXyz(abc);
return bean;
}
// Or check for annotation using applicationContext
MyAnnotation myAnnotation = this.applicationContext.findAnnotationOnBean(beanName, MyAnnotation.class);
if (myAnnotation != null) {
// do your custom logic here
bean.setXyz(myAnnotation.getAbc());
return bean;
}
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
// Optional part. If you want to use Autowired inside BeanPostProcessors
// you can use Lazy annotation. Otherwise they may skip bean processing
@Lazy
@Autowired
public MyBeanPostProcessor(MyLazyAutowiredBean myLazyAutowiredBean) {
}
}
I guess if it's similar to ConfigurationProperties
, then the class ConfigurationPropertiesBindingPostProcessor
that binds properties to beans may serve as an example. It implements BeanPostProcessor
and does the binding in the postProcessBeforeInitialization
method. This method has the following Javadocs:
" Apply this BeanPostProcessor to the given new bean instance before any beaninitialization callbacks (like InitializingBean's afterPropertiesSetor a custom init-method). The bean will already be populated with property values.The returned bean instance may be a wrapper around the original. "
One possible solution is to write a custom setter and annotate it with @Autowired, like this:
@Autowired
public void setExample(Example example)
{
// Do your stuff here.
this.example = example;
}
However, I don't recommend this practice of modifying a bean before autowiring since it can lead to poor code mantainability and it may be counter-intuitive for other people that need to work on your code too.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.