spring学习(六)——1.2 后置处理器 BeanPostProcessor

参考文章:

http://www.iocoder.cn/

Bean初始化的后置处理器,即BeanPostProcessor 接口

 

它为我们提供了丰富的可扩展点,它实现了在 Bean 完成实例化后,如果我们需要对其进行一些配置、增加一些自己的处理逻辑

BeanPostProcessor 在源码中的逻辑

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		//安全模式
		if (System.getSecurityManager() != null) {
			// ** Aware 方法,对特殊的 bean 处理:Aware、BeanClassLoaderAware、    BeanFactoryAware
			.....
		}
		else {
			// ** Aware 方法,对特殊的 bean 处理:Aware、BeanClassLoaderAware、BeanFactoryAware
			.....
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			// 初始化 bean的前置处理
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			// **初始化方法
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		.....
		return wrappedBean;
	}

 

@Override
	public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		// 遍历 BeanPostProcessor
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			// 处理
			Object current = processor.postProcessBeforeInitialization(result, beanName);
			// 为空则返回 existingBean
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

需要注意的时候假如factory中不存在BeanPostProcessor,创建bean的时候则不会触发其内容

BeanPostProcessor 的基本原理

  • 可以理解为是 Spring 的一个工厂钩子(如 Aware InitializingBeanDisposableBean)
  • 一般普通的 BeanFactory 是不支持自动注册 BeanPostProcessor 的,需要我们手动调用 #addBeanPostProcessor(BeanPostProcessor beanPostProcessor) 方法进行注册
  • 但是 ApplicationContext 可以在其 bean 定义中自动检测所有的 BeanPostProcessor 并自动完成注册,同时将他们应用到随后创建的任何 Bean 中

整个Processor的处理逻辑为

spring学习(六)——1.2 后置处理器 BeanPostProcessor

Demo

实现BeanPostProcessor接口类

public class BeanPostProcessorTest implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("Bean [" + beanName + "] 开始初始化");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("Bean [" + beanName + "] 完成初始化");
        return bean;
    }

    public void display(){
        System.out.println("hello BeanPostProcessor!!!");
    }

}

spring注入bean,但是不添加BeanPostProcessor

public static void main(String[] args) {
        //spring2 中注入BeanPostProcessorTest
        ClassPathResource resource = new ClassPathResource("spring2.xml");
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
        reader.loadBeanDefinitions(resource);

        BeanPostProcessorTest test = (BeanPostProcessorTest) factory.getBean("beanPostProcessorTest");
        test.display();
    }

而打印内容

00:35:17.331 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Eagerly caching bean 'beanPostProcessorTest' to allow for resolving potential circular references
00:35:17.332 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'beanPostProcessorTest'
hello BeanPostProcessor!!!

spring注入bean,但是添加BeanPostProcessor

public static void main(String[] args) {
        //spring2 中注入BeanPostProcessorTest
        ClassPathResource resource = new ClassPathResource("spring2.xml");
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        BeanPostProcessorTest beanPostProcessorTest = new BeanPostProcessorTest();
        // 假如processor后
        factory.addBeanPostProcessor(beanPostProcessorTest);

        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
        reader.loadBeanDefinitions(resource);
        BeanPostProcessorTest test = (BeanPostProcessorTest) factory.getBean("beanPostProcessorTest");
        test.display();
    }
 

打印内容

00:42:24.778 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Eagerly caching bean 'beanPostProcessorTest' to allow for resolving potential circular references
Bean [beanPostProcessorTest] 开始初始化
Bean [beanPostProcessorTest] 完成初始化
00:42:24.780 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'beanPostProcessorTest'
hello BeanPostProcessor!!!
spring学习(六)——1.2 后置处理器 BeanPostProcessor

自动注入!!!

spring的application会自动检测processors并注入

AbstractApplicationContext.java中

/**
	 * Instantiate and invoke all registered BeanPostProcessor beans,
	 * respecting explicit order if given.
	 * <p>Must be called before any instantiation of application beans.
	 */
	protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	}
  •  BeanPostProcessor 的作用域是容器级别的,它只和所在的容器相关 ,当 BeanPostProcessor 完成注册后,它会应用于所有跟它在同一个容器内的 bean
  • BeanFactory ApplicationContext BeanPostProcessor 的处理不同,ApplicationContext 会自动检测所有实现了 BeanPostProcessor 接口的 bean,并完成注册,但是使用 BeanFactory 容器时则需要手动调用 AbstractBeanFactory#addBeanPostProcessor(BeanPostProcessor beanPostProcessor) 方法来完成注册
  • ApplicationContext BeanPostProcessor 支持 Ordered,而 BeanFactory BeanPostProcessor 是不支持的,原因在于ApplicationContext 会对 BeanPostProcessor 进行 Ordered 检测并完成排序,而 BeanFactory 中的 BeanPostProcessor 只跟注册的顺序有关。