PostProcessor
Why do you want to have this post processor this interface, understand the Spring container friend should know that all the ApplicationContext needs to call AbstractApplicationContext# refresh method, it is a template method, Since you are using the template method design pattern, you should provide hooks, which are hook functions. PostProcessor was designed to fulfill this custom extension requirement.
UML
- BeanPostProcessor
- BeanFactoryPostProcessor
PostProcessor overview
BeanFactoryPostProcessor
Container level post-processor with only one method declared inside. Spring calls the post-processor in the order it is declared, and BeanFactoryPostProcessor hands the container itself over to the interface implementation classes during container initialization. Once you get the container, you can do a lot of customization.
@FunctionalInterface
public interface BeanFactoryPostProcessor {
/**
* Modify the application context's internal bean factory after its standard
* initialization. All bean definitions will have been loaded, but no beans
* will have been instantiated yet. This allows for overriding or adding
* properties even to eager-initializing beans.
* @param beanFactory the bean factory used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
Copy the code
BeanDefinitionRegistryPostProcessor
From the annotation container parsing BeanDefinition chapter, you’ll learn BeanDefinitionRegistryPostProcessor is a special kind of Spring BeanFactoryPostProcessor, but Spring will give priority to deal with this kind of post processor, Some of the spring BeanFactoryPostProcessor reprocessing routine. This can be interpreted as a VIP BeanFactoryPostProcessor, which takes precedence over the regular BeanFactoryPostProcessor. A dedicated post-registration processing method is also declared internally. postProcessBeanDefinitionRegistry
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
/**
* Modify the application context's internal bean definition registry after its
* standard initialization. All regular bean definitions will have been loaded,
* but no beans will have been instantiated yet. This allows for adding further
* bean definitions before the next post-processing phase kicks in.
* @param registry the bean definition registry used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
Copy the code
BeanPostProcessor
You can implement BeanPostProcessor to affect the life cycle of all beans, including pre – and post-initialization processing. You’ll come across the BeanPostProcessor later in the life cycle of Spring beans
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 {
returnbean; }}Copy the code
Use postProcessor
MyBeanFactoryPostProcessor
- Based on the object
@Data
public class Root {
private String name;
private String description;
private boolean isRoot;
}
Copy the code
- The BeanDefinition is injected into the container through a post-processor
package com.xjm.bean.postprocessor;
import com.xjm.model.Root;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.*;
import org.springframework.context.annotation.Configuration;
/ * * *@author jaymin
* 2021/1/7 23:10
*/
@Configuration
public class MyBeanFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {}/** * Modifies the internal BeanDefiniton registry of the application context after standard initialization. <br> * All regular bean definitions will be loaded, but no beans have been instantiated yet. <br> * This allows more Beandeinitions to be added before the next post-processing phase begins. < br > * Spring factory level of Spring BeanFactoryPostProcessor, priority level is higher than conventional Spring BeanFactoryPostProcessor. < br > * integrate third-party framework, You can implement this registration interface for BeanDefinition registration. Such as Mybatis.<br> * Design pattern: Chain of responsibility pattern < BR > *@param registry the bean definition registry used by the application context
* @throws BeansException
*/
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
BeanDefinition beanDefinition = getBeanDefinition(Root.class);
registry.registerBeanDefinition("root",beanDefinition);
System.out.println("Customer BeanPostProcessors execute.");
}
private BeanDefinition getBeanDefinition(Class
clazz){
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(clazz).getBeanDefinition();
returnbeanDefinition; }}Copy the code
- test
@ComponentScan based on its own package path to modify, here the program is running properly, indicating that Root is registered in the container.
@Configuration
@ComponentScan(value = "com.xjm")
public class BeanDefinitionDemoByAnnotation {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AnnotationContextDemo.class);
Root root = applicationContext.getBean("root", Root.class); }}Copy the code
MyBeanPostProcessor
Simply implement BeanPostProcessor by observing the scope of its behavior.
@Configuration
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
@Nullable
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName + " invoking MyBeanPostProcessor#postProcessBeforeInitialization");
return bean;
}
/** * all beans can be operated uniformly *@param bean the new bean instance
* @param beanName the name of the bean
* @return
* @throws BeansException
*/
@Override
@Nullable
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName + " invoking MyBeanPostProcessor#postProcessAfterInitialization");
returnbean; }}Copy the code
- result
As you can see, the implementation of MyBeanPostProcessor affects the initialization of all beans.
conclusion
- The post-processor is the extensibility hook interface that Spring leaves for developers.
- From the rear processor, it can be briefly divided into:
BeanFactoryPostProcessor
andBeanPostProcessor
Among them,BeanFactoryPostProcessor
You can manipulate containers,BeanPostProcessor
Affects the life cycle of all beans. BeanDefinitionRegistryPostProcessor
It’s a special kind ofBeanFactoryPostProcessor
Is superior to otherBeanFactoryPostProcessor
The execution.
Further reading
Spring BeanPostProcessor Spring BeanPostProcessor Spring BeanPostProcessor