Spring BeanPostProcessor beans are a special kind of beans that get created before any other beans and Spring allows you to assign customize callbacks to it. Spring provides the BeanPostProcessor
interface, you can implement its methods to provide your own instantiation logic and dependency resolution logic.
NOTE – the following before working with BeanPostProcessor
.
- BeanPostProcessor methods are executed after the Spring IoC finishes instantiating, configuring, and initializing a bean.
- You can plug in one or more custom
BeanPostProcessor
implementations. - When working with multiple Bean Postprocessors, you should implement the
Ordered
interface to control the order in which these processors get executed. - Remember, the
BeanPostProcessor
instances are scoped per container.
Example of BeanPostProcessor usage
All you need to do is to implement the interface BeanPostProcessor
in your custom class. The interface looks as below, which means you can implement the method that you like and each of them returns bean
by default.
public interface BeanPostProcessor { @Nullable default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } @Nullable default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } }
All you need to do is implement the interface and implement the callback methods. Below code explains the simple use of the Spring BeanPostProcessor
.
@Component public class TraceBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("Inside postProcessBeforeInitialization - " + beanName); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("Inside postProcessAfterInitialization - " + beanName); return bean; } }
@Component public class ExampleBean { @PostConstruct public void initData() { System.out.println("Your custom initialization code goes here..."); } @PreDestroy public void clearData() { System.out.println("Your custom destroy code goes here..."); } }
@Configuration @ComponentScan("core.bean.postprocessor") public class ExampleConfig { //Extra config goes }
public class TestExampleBean { public static void main(String[] args) { ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(ExampleConfig.class); context.getBean(ExampleBean.class); //This is important context.registerShutdownHook(); } }
Output:
Inside postProcessBeforeInitialization exampleConfig Inside postProcessAfterInitialization exampleConfig Inside postProcessBeforeInitialization exampleBean Your custom initialization code goes here... Inside postProcessAfterInitialization exampleBean Your custom destroy code goes here...
As you can see in the above output, the bean post-processor methods get invoked twice, once per bean. This is because Spring IoC creates 2 beans here (exampleConfig, and exampleBean).
You can have multiple custom BeanPostProcessor classes in your Spring application, but remember to implement the
Ordered
interface as well.
A Practical use case of BeanPostProcessor
A practical use case of a bean Post Processor is when you want to wrap the original IoC-created bean in a proxy instance for example when you use @Transactional, Spring-AOP or BeanValidationPostProcessor. I have listed some of the Spring framework classes that make use of the bean post-processor interface.
- The BootstrapContextAwareProcessor in Spring-Tx.
- The ServletContextAwareProcessor in Spring-Web.
- The PersistenceAnnotationBeanPostProcessor in Spring-orm project.
I hope to have provided enough information on this topic. Please share your thoughts in the comments below. I highly encourage you to check out the article related to the Spring bean lifecycle.
Leave A Comment