Spring技术内幕笔记(十二)------BeanPostProcessor的实现

什么是BeanPostProcessor

BeanPostProcessor是使用Ioc容器的时经常会遇到的一个特性,这个Bean的后置处理器是一个监听器。将后置处理器向Ioc容器中注册之后,容器中管理的Bean具备了接收Ioc容器事件回调的能力。

BeanPostProcessor是一个接口类,它具有两个接口方法,一个是PostProcessorBeforeInitialization,在Bean的初始化前提供回调入口,一个是postProcessorAfterInitialization,在Bean的初始化后回调入口,这两个回调的触发都和容器Bean的生命周期有关。

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

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessBeforeInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

从方法名上我们就可以看出来这个方法是用来调用调用我们的beanPostBeforeInitialization()方法的,
其中getBeanPostProcessor()方法是用来获取当前容器中已经注册成功的所有BeanPostProcessor,让我们来看看。

	/**
	 * Return the list of BeanPostProcessors that will get applied
	 * to beans created with this factory.
	 */
	public List<BeanPostProcessor> getBeanPostProcessors() {
		return this.beanPostProcessors;
	}

这个方法实现只有一行,直接返回的是beanPostProcessors这个静态变量,那么问题来了,这个静态变量是什么时候被赋值的呢,或者说我们的BeanPostProcessor是什么时候被注册到我们的IOC容器中的呢。让我们回到IOC的启动过程中,在refresh()方法中调用了这样一个方法invokeBeanFactoryPostProcessors();这个方法就是用来注册我们的BeanPostProcessor的,具体的细节我们以后在分析。

既然我们现在知道了postBeforeProcessorInitialization是如何调用的,那么我们现在看一下postAfterProcessorInitialization

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

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

从代码中我们可以看出来,applyBeanPostProcessorAfterInitializa的调用方式和applyBeanPostProcessorsBeforInitialization的调用方式基本相似,都是循环调用before或者after方法。

接下来我们向上看看是由哪个方法调用这两个方法的

	/**
	 * Initialize the given bean instance, applying factory callbacks
	 * as well as init methods and bean post processors.
	 * <p>Called from {@link #createBean} for traditionally defined beans,
	 * and from {@link #initializeBean} for existing bean instances.
	 * @param beanName the bean name in the factory (for debugging purposes)
	 * @param bean the new bean instance we may need to initialize
	 * @param mbd the bean definition that the bean was created with
	 * (can also be {@code null}, if given an existing bean instance)
	 * @return the initialized bean instance (potentially wrapped)
	 * @see BeanNameAware
	 * @see BeanClassLoaderAware
	 * @see BeanFactoryAware
	 * @see #applyBeanPostProcessorsBeforeInitialization
	 * @see #invokeInitMethods
	 * @see #applyBeanPostProcessorsAfterInitialization
	 */
	 //这个方法主要是初始化Bean实例,调用在容器的回调方法和Bean的初始化方法
	protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}

        //这里就是我们对Bean的后置处理器的postProcessorBeforeInitialization的回调方法的调用
		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

        //调用bean的初始化方法,这个初始化方法是在BeanDefinition中通过init-method属性指定的,同时如果Bean实现了InitializingBean接口,那么这个Bean的afterPropertiesSet实现也会被调用
		try {
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		
		//这里就是调用我们的beanPostAfterProcessor的地方
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值