Customizing beans using a BeanPostProcessor

The BeanPostProcessor is an important extension point in Spring. It can modify bean instances in any way. It is used to enable a powerful feature such as the AOP proxy. You can write your own BeanPostProcessor in your application to create a custom post-processor--the class must implement the BeanPostProcessor interface. Spring provides several implementations of BeanPostProcessor. In Spring, the BeanPostProcessor interface has two callback methods, as follows:

    public interface BeanPostProcessor { 
      Object postProcessBeforeInitialization(Object bean, String 
beanName) throws BeansException; Object postProcessAfterInitialization(Object bean, String
beanName) throws BeansException; }

You can implement these two methods of the BeanPostProcessor interface to provide your own custom logic for bean instantiation, dependency-resolution, and so on. You can configure multiple BeanPostProcessor implementations to add custom logic to the Spring container. You can also manage the order of execution of these BeanPostProcessor by setting the order property. BeanPostProcessor work on Spring bean instances after instantiation of the bean by the Spring container. The scope of the BeanPostProcessor is within the Spring container, which means that beans that are defined in one container are not post-processed by a BeanPostProcessor defined in another container.

Any class in a Spring application is registered as a post-processor with the container; it is created for each bean instance by the Spring container. And the Spring container calls the postProcessBeforeInitialization() method before the container initialization methods (Initializing Bean's afterPropertiesSet() and the bean's init method). It also calls the postProcessAfterInitialization() method after any bean initialization callbacks. The Spring AOP uses the post-processor to provide proxy-wrapping logic (Proxy design pattern) although we can take any action by using the post-processor.

Spring's ApplicationContext automatically detects those beans which implement the BeanPostProcessor interface, and registers these beans as post-processors. These beans are called at the time of any other bean creation. Let's explore the following example of BeanPostProcessor.

Let's create a custom bean post-processor as follows:

    package com.packt.patterninspring.chapter5.bankapp.bpp; 
    import org.springframework.beans.BeansException; 
    import org.springframework.beans.factory.config.BeanPostProcessor; 
    import org.springframework.stereotype.Component; 
    @Component 
    public class MyBeanPostProcessor implements 
BeanPostProcessor { @Override public Object postProcessBeforeInitialization
(Object bean, String beanName) throws BeansException { System.out.println("In After bean Initialization
method. Bean name is "+beanName); return bean; } public Object postProcessAfterInitialization(Object bean, String
beanName) throws BeansException { System.out.println("In Before bean Initialization method. Bean
name is "+beanName); return bean; } }

This example illustrates basic usage, here this example shows a post-processor prints the string to the system console for each bean registered with the container. This MyBeanPostProcessor class annotated with @Component that means this class same as other bean class in the application context, now run the following demo class. Please refer to the following code:

    public class BeanLifeCycleDemo { 
      public static void main(String[] args) { 
        ConfigurableApplicationContext applicationContext = new 
AnnotationConfigApplicationContext(AppConfig.class); applicationContext.close(); } }

This is the output that we'll get on the console:

As you can see in the preceding output, a string of both the callback methods is printed for each bean method in the Spring container. Spring provides many pre-implemented BeanPostProcessor for some specific features, as follows:

  • RequiredAnnotationBeanPostProcessor
  • AutowiredAnnotationBeanPostProcessor
  • CommonAnnotationBeanPostProcessor
  • PersistenceAnnotationBeanPostProcessor

The namespace <context:annotation-config/> in the XML configuration enables several post-processor in the same application context in which it is defined.

Let us now move on to our next section, and see how we can enable the Initializer extension point by using BeanPostProcessor.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset