spring源码阅读之 BeanFactoryPostProcessor

前言

Spring中BeanFactoryPostProcessor和BeanPostProcessor都是Spring初始化bean时对外暴露的扩展点。两个接口从名字看起来很相似,但是作用及使用场景却不同。
前面我们已经大致了解了BeanPostProcessor的作用,可以点击spring源码阅读之BeanPostProcessor
Spring IoC容器允许BeanFactoryPostProcessor在容器实例化任何bean之前读取bean的定义(配置元数据),并可以修改它。同时可以定义多个BeanFactoryPostProcessor,通过设置’order’属性来确定各个BeanFactoryPostProcessor执行顺序。

注册一个BeanFactoryPostProcessor实例需要定义一个Java类来实现BeanFactoryPostProcessor接口,并重写该接口的postProcessorBeanFactory方法。通过beanFactory可以获取bean的定义信息,并可以修改bean的定义信息。这点是和BeanPostProcessor最大区别

其实我可以简单高度概括一下: BeanFactoryPostProcessor <---------对应修改-----------> BeanDefinition
BeanPostProcessor <---------对应修改-----------> Bean

源码

public interface BeanFactoryPostProcessor {
       
      /**
 * spring 的扩展点之一
 * 实现该接口,可以在spring的bean创建之前修改bean的定义属性
 * spring运行BeanfactoryPostoryProceesor 在容器实例化任何其他bean之前读取配置云数据,
 * 并可以根据需要进行修改,例如可以把bean的scop从singleton修改成为prototypo,也可以吧吧property的值给改掉
 * 可以同时配置多个BeanFactoryPostoProcessor,并通过"order"属性来控制各个BeanFactoryPostProcessor的执行顺序,
 * BeanFactoryPostProcessor是在spring容器加载了bean的定义文件之后,在bean实例化之前执行的
 * 可以写一个离职来测试这个功能
 */
        /** 
         * 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;  
      
    }

自定义beanFactoryPostProcessor

package com.wfg.beanfactorypostprocessor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;

/**
 * spring
 *
 * @Title: com.wfg.beanfactorypostprocessor
 * @Date: 2021/1/1 0001 21:49
 * @Author: wfg
 * @Description:
 * @Version:
 */
@Component
public class MyBeanFactoryProcessor implements BeanFactoryPostProcessor {
     
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
     
		System.out.println("====postProcessBeanFactory====");
		String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
		for (String beanName:beanDefinitionNames ) {
     
			System.out.println("beanName  :  "+beanName);
			if("userDaoImpl".equals(beanName)){
     
				BeanDefinition userDaoImpl = beanFactory.getBeanDefinition(beanName);
				userDaoImpl.setScope(ConfigurableBeanFactory.SCOPE_PROTOTYPE);
			}
		}
	}
}

测试

public class TestUserDao {
     
	public static void main(String[] args) {
     
		AnnotationConfigApplicationContext configApplicationContext =
				new AnnotationConfigApplicationContext(AppConfig.class);
		//configApplicationContext.register(UserDaoImpl.class);
		//configApplicationContext.refresh();
		UserDao bean = configApplicationContext.getBean(UserDaoImpl.class);
		UserDao bean1 = configApplicationContext.getBean(UserDaoImpl.class);
		System.out.println(bean.hashCode()+"======="+bean1.hashCode());
		bean.query();
	}
}

发现hashcode不一致说明不是同一个对象了
spring源码阅读之 BeanFactoryPostProcessor_第1张图片

在Spring中内置了一些BeanFactoryPostProcessor实现类:

org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
org.springframework.beans.factory.config.PropertyOverrideConfigurer
org.springframework.beans.factory.config.CustomEditorConfigurer:用来注册自定义的属性编辑器

spring源码阅读之 BeanFactoryPostProcessor_第2张图片

你可能感兴趣的:(#,SSH之Spring,spring,java,BeanFactory,Processor,PostProcessor)