Spring(二) BeanFactory的扩展点简述

基本创建bean的流程

简单的思考一下,如果我们想通过一个Class进行反射创建bean需要的过程。不管作用域、工厂等扩展问题

1、找到具体的类

2、创建bean实例

        根据bean定义中配置的参数,找到合适的构造方法

        通过该构造方法利用反射创建bean

3、根据配置的属性对当前bean进行填充

4、初始化bean

        比如说调用其init方法

基于基本流程的扩展点

往往我们需要在bean创建的过程中预留足够的扩展方法,比如说在实例化前后,初始化前后都可以进行一定的方法增强。Spring就预留了这些方法点。接下来看下这些扩展点是如何实现的

BeanPostProcessor家族简介

List<BeanPostProcessor> beanPostProcessors是抽象工厂AbstractBeanFactory中的属性,他记录了初始化的增强器以及基于当前接口扩展的初始化增强器。简单的看下两个类

BeanPostProcessor 用来完成初始化的前置以及后置增强,定义如下

public interface BeanPostProcessor {

    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;

	Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
InstantiationAwareBeanPostProcessor用来完成实例化的前置和后置增强,定义如下
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

	
	Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException;

	
	boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException;

	
	PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException;

}

看下整个织入的过程。

实例化前置增强

在上述过程中1之前预留了实例化前置的扩展点,这个地方同时也是aop扩展点的使用方法,在实例化前使用增强方法看看是否生成新的bean,如果生成的话,则直接返回。

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// Make sure bean class is actually resolved at this point.
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
				if (result != null) {
					return result;
				}
			}
		}
		return null;
	}

实例化后置增强

其实现主要介于上述过程的2-3之间,但是具体实现在填充属性的populateBean方法中。在实例化之后属性填充之前会用到Spring的实例化后置增强方法,其具体实现在populateBean中。具体如下

protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
	    // .....................
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						return;
					}
				}
			}
		}
       // .....................
}

其实和前置增强很像,就是遍历BeanPostProcessor,然后去调用其后置增强方法postProcessAfterInstantiation。

初始化前增强

其初始化方法位于org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean在初始化过程中的步骤主要是

1、调用aware方法进行注入属性

2、调用初始化的前置增强

3、进行初始化调用,比如指定的init-method

4、初始化后的增强调用

下面简单描述一下几个增强的调用源码

初始化前的aware增强

代码很简单,判断当前实例化的bean是否实现了对应的aware,如果实现了的话,则把对应的信息作为入参调用对应的bean方法。

private void invokeAwareMethods(final String beanName, final Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof BeanNameAware) {
				((BeanNameAware) bean).setBeanName(beanName);
			}
			if (bean instanceof BeanClassLoaderAware) {
				((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
			}
			if (bean instanceof BeanFactoryAware) {
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}
	}

初始化前的BeanPostProcessor增强

其实初始化前的调用和其他BeanPostProcessor增强并无太大差别,只是调用的是初始化前的方法。如下

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

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

初始化后增强

初始化后的增强也和其他增强差别不是很大。具体调用如下:

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

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值