Sping source code (seven) - post processor (custom post processor)

The previous article briefly introduced the execution process of the invokeBeanFactoryPostProcessors method in Spring, as well as the introduction of the BFPP and BDRPP classes. In this article, we will customize the implementation of a post-processor of a class.

Custom PostProcessor
There are two ways to customize PostProcessor, both of which are implemented according to the parameters in the invokeBeanFactoryPostProcessors() method, one of which is added to the beanFactory, and the other is added to the parameter List<BeanFactoryPostProcessor>. The implementation of the two methods is not much different. This article will explain how to add to the parameter List.

Remember that in the source code, PostProcessorNames will be obtained multiple times according to the BDRPP type? In the process of custom implementation, we will restore the BDRPP class created when executing the postProcessBeanDefinitionRegistry() method, and the RegistryCustomerBDRPP class is to be added.

public class RegistryCustomerBDRPP implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
    
    
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    
    
        System.out.println("执行自定义RegistryCustomerBDRPP ,调用postProcessBeanDefinitionRegistry方法");
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    
    
        System.out.println("执行自定义RegistryCustomerBDRPP ,调用postProcessBeanFactory方法");
    }

    @Override
    public int getOrder() {
    
    
        return 0;
    }
}

Create RegistryCustomerBDRPP by executing the ppbdr method in the MyCustomerBeanDefinitionRegistryPostProcessor class.

public class MyCustomerBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
    
    
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    
    
        BeanDefinitionBuilder customer = BeanDefinitionBuilder.rootBeanDefinition(RegistryCustomerBDRPP.class);
        System.out.println("在BDRPP中注册新的 BDRPP");
        registry.registerBeanDefinition("customer",customer.getBeanDefinition());
        System.out.println("自定义BDRPP------------调用方法MyCustomerBeanDefinitionRegistryPostProcessor");
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    
    
        System.out.println("Customer -----------实现BDRPP中postProcessBeanFactory方法");
    }

    @Override
    public int getOrder() {
    
    
        return 0;
    }
}

The class has been created, and the next step is how to add it to the parameter List<BeanFactoryPostProcessor>. Looking at the source code, it is not difficult to find that when obtaining List<BeanFactoryPostProcessor>, it is obtained through the getBeanFactoryPostProcessors() method. For the specific source code execution logic, please refer to the previous Sping source code (7) - post-processor for a detailed explanation.

source code

	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    
    

		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
		//省略无用代码
		}
	}
	//具体调用方法
	public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
    
	//省略无用代码
}

In the Spring source code, if there is a get method, there must be a corresponding add() or set() method to fill in the value.
By clicking, you can find that the getBeanFactoryPostProcessors() method is implemented in the AbstractApplicationContext. The AbstractApplicationContext class relationship diagram is as follows. You can see that there is a ClassPathXmlApplicationContext in the subclass. Therefore, we can customize it by rewriting addBeanFactoryPostProcessor() by implementing the ClassPathXmlApplicationContext class. Add the PostProcessor into it.

AbstractApplicationContext

public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext {
    
    
	public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
    
    
			return this.beanFactoryPostProcessors;
		}
	
	@Override
		public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
    
    
			this.beanFactoryPostProcessors.add(postProcessor);
		}
}		

class diagram
insert image description here

addBeanFactoryPostProcessor
In this way, when the invokeBeanFactoryPostProcessors method is executed, the BDRPP we added will be obtained in the getBeanFactoryPostProcessors() method.

public class MyClassPathXmlApplicationContext extends ClassPathXmlApplicationContext {
    
    
	  	@Override
	    protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
    
    
	        super.addBeanFactoryPostProcessor(new MyCustomerBeanDefinitionRegistryPostProcessor());
	    }
}	    

And if you want to add custom BDRPP to BeanFactory, it is even easier. After customizing BDRPP, you can let Spring recognize your BDRPP through the <bean> tag. When executing invokeBeanFactoryPostProcessors, it will be obtained directly in BeanFactory.

Guess you like

Origin blog.csdn.net/weixin_43936962/article/details/132500097