Origin of Spring [Simple Use and Introduction of Post Processor BeanPost Processor]

Posted by ZaZall on Tue, 30 Jul 2019 08:32:53 +0200

BeanPost Processor is officially defined as a factory hook, also known as a post processor. It allows you to customize new bean instances, such as checking tag interfaces or wrapping them with proxies. The application context can automatically detect BeanPostProcessor bean s in its bean definition and apply them to any subsequently created beans.

BeanPostProcessor class

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;
    }
}

Since it is an interface, we must implement it if we want to use it. We create a SimpleBeanPostProcessor class to implement the interface.

@Component
public class SimpleBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInitialization - " + bean.getClass().getName() + " - " + beanName);
        return null;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization  - " + bean.getClass().getName() + " - " + beanName);
        return null;
    }
}

In the implementation class, we simply print the information of the bean and the bean Name.

If you want the post processor to work, you have to start the spring container. We use Annotation Config Application Context to start the spring container. And inject a custom Bean into spring

@ComponentScan("spring.postProcessor")
@Configuration("spring.postProcessor.run")
public class Run {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Run.class);
        applicationContext.close();
    }

    /**
     * You can specify initMethod by @Bean
     * @return
     */
    @Bean(initMethod = "init")
    public MyBean myBean() {
        return new MyBean();
    }
}

The MyBean code is as follows

@Data
public class MyBean {
    private String beanName;
    private String className;
    public MyBean() {
        System.out.println("MyBean constructor");
    }
    public void init() {
        System.out.println("MyBean is init");
    }
}

The results are as follows.

postProcessBeforeInitialization - spring.postProcessor.Run$$EnhancerBySpringCGLIB$$db1dd68 - spring.postProcessor.run
postProcessAfterInitialization  - spring.postProcessor.Run$$EnhancerBySpringCGLIB$$db1dd68 - spring.postProcessor.run
MyBean constructor
postProcessBeforeInitialization - spring.postProcessor.MyBean - myBean
MyBean is init
postProcessAfterInitialization  - spring.postProcessor.MyBean - myBean

As can be seen from the typing results, the post processor executes after the bean's construction method is executed. The postProcessBeforeInitialization and postProcessAfterInitialization methods of the post processor are executed before and after the init method of the bean, respectively. And the post processor works on all beans in spring.
In the spring source class org. spring framework. beans. factory. support. AbstractAutowireCapableBeanFactory's method initializeBean, we can see why this is done.

These are the simple ways to use spring's post processor and the timing of execution. As for specific practical use cases, they will be explained in the next article!

Topics: Java Spring