Spring在初始化过程中的扩展机会

Spring加载上下文,进行配置解析,注册BeanDefinition之后,会通过getBean方法触发bean的创建注入。

1、在创建bean对象之前,会调用AbstractAutowrieCapableBeanFactory的resolveBeforeInstantiation方法中,获得创建bean之前的扩展机会。假如这个方法返回了一个bean对象,则使用该对象作为对应beanName实例对象。这个方法会顺序调用:

    1)InstantitionAwareBeanPostProcessor的postBeforeInstantiation方法

    2)BeanPostProcessor的postProcessorAfterInstantiation方法

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;
	}

2、在准备执行bean的对象创建时,会调用determinConstructFromBeanPostProcessors方法来提供对bean的构造函数的扩展机会。这个方法中是调用SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors方法返回Constructor数组用于构造对象。如下:

protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
			throws BeansException {

	if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
				SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
				Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
				if (ctors != null) {
					return ctors;
				}
			}
		}
	}
	return null;
}

3、创建完Bean对象后对MergedBeanDefinition的扩展:

protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
	for (BeanPostProcessor bp : getBeanPostProcessors()) {
		if (bp instanceof MergedBeanDefinitionPostProcessor) {
			MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
			bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
		}
	}
}

4、对象被创建后,调用popularBean进行属性的注入。在注入属性前执行如下逻辑:

if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
	for (BeanPostProcessor bp : getBeanPostProcessors()) {
		if (bp instanceof InstantiationAwareBeanPostProcessor) {
			InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
			if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
				continueWithPropertyPopulation = false;
				break;
			}
		}
	}
}

    进行bean的创建(初始化)后的扩展。

5、经过第4步的扩展逻辑后,紧跟着就是对bean属性的注入了。比如class A 使用构造函数创建后,class A中的两个属性,int  b 以及class D;注入属性b以及通过注入模式触发类D的依赖注入。在属性b和d的实例获取后,执行属性获得后的扩展: 

for (BeanPostProcessor bp : getBeanPostProcessors()) {
	if (bp instanceof InstantiationAwareBeanPostProcessor) {
		InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
		pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
		if (pvs == null) {
			return;
		}
	}
}

6、紧跟着popularBean方法之后,是initializtionBean方法。在这个方法中会看到很多平时我们使用到的扩展,执行顺序如下(从这里也可以看到常用的扩展是按照怎样的顺序执行。):   

    1)各种Aware接口。比如BeanNameAware, BeanClassloaderAware,BeanFactoryAware

    2)BeanPostProcessor的postProcessorBeforeInitialization方法

    3)init方法。先执行InitializationBean的afterPropertiesSet方法,然后是自定义的init方法,比如在xml配置文件中使用init-method进行定义,或者使用@PostConstruct注解标记的初始化方法。

    4)BeanPostProcessor的postProcessorAfterInitialization方法。

上述流程是在使用getBean触发对bean的创建以及依赖注入的过程中的扩展机会,所相关的扩展都属于bean级别的扩展。Spring除了bean对象级别的扩展之外,还提高了容器级别的扩展,比如BeanFactoryPostProcessor,不在当前文章的介绍范围之内,会有专门的文章单独介绍

转载于:https://my.oschina.net/evermaze/blog/1594273

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值