spring源码笔记(四) ----Bean的创建源码调用链分析

spring中存储的Bean有些是spring框架自己提供并且自己使用的,他们由spring自行创建并且由框架内部按需调用;有些是用户创建好并交付spring进行管理的。我们将后一种bean称之为用户自定义Bean,我们重点解释这种Bean的创建流程。

我们首先介绍在没有循环依赖,并且没有AOP代理的情况下,spring中Bean的创建流程。这是spring中用户自定义Bean的最普通的创建流程。

创建Bean的前提条件是否具备?

spring中用户自定义Bean可以创建需要几个前提,首先是该Bean对应的BeanDefinition已经创建完成,并且在BeanFactoryPostProcessor接口的目标方法(如果有的话),已经调用过,同时各种自定义的BeanPostProcessor实现类已经完成创建。这时候,万事俱备,就开始了Bean的创建。

在封装复杂的源码中找到创建Bean的关键方法

不论是以注解的方式启动spring环境还是以XML方式启动,在对应的ApplicationContext上下文对象的构造方法中都要调用一个很重要的方法refresh( )。Bean的实例化发生在refresh内部,finishBeanFactoryInitialization(beanFactory);这个方法的调用中。

在finishBeanFactoryInitialization(beanFactory)方法内部,经过一系列调用,创建流程会转入到如下方法中:

public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}

		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					
						......//此处非普通Bean创建流程,省去
				}
				else {
					//外部有for循环,用来循环创建所有Bean,将每个beanName排除factoryBean后尝试get,如果没有get到,就进入创建逻辑。此处返回值一定是存到单例池缓存中的
					getBean(beanName);
					
				}
			}
		}
             ......

可以看到,所有需要创建的Bean都保存到一个叫做beanNames的List中,对这个list中的beanName进行遍历, 拿到每一个beanName对应的BeanDefinition。如果这个BeanDefinition同时满足非抽象类,不存在懒加载,并且是单例的,这里就要对其进行创建。创建流程经过一系列判断,最终走到了getBean(beanName)这个环节;

为什么是getBean()?

此处大家想一想,既然Bean还没有创建,调用的方法为啥不是InitializationBean呢?此处在后边讲到依赖注入的时候还会细讲:是因为在某些类的创建过程中因为存在循环依赖,或者DI的需要,进行了提前的创建,故而这里是可以get到实例的。而大多数Bean没有提前创建的,就需要在此处进行创建。

既然,有些类已经有实例,而有些类没有。可以想象到getBean内部的流程应该会是这样的:

     Object bean = getInstance(beanName);

     if(bean != null){
         return bean;
     }

     return createNewInstance(beanName);
     

spring 在实际当中的操作比这个要复杂许多,流程如下,在关键的地方我都进行了注释

 

可以看到,return 返回的 Bean来自sharedInstance;虽然这个sharedInstance通过getObjectForBeanInstance()方法进行了处理。但是最终的return 的bean的来源,是sharedInstance;

sharedInstance又从何而来呢?很显然来自于getSingleton( )方法的返回值,getSingleton( )内部返回了哪个值呢:就是29行createBean(beanName,mbd,args)的返回值。

再进入这个方法内部,就来到了处理Bean创建流程的具体方法doCreateBean(beanName,mbdToUse,args);

下面给出,一个不包含循环依赖,不进行AOP代理的普通Bean的完整调用链:doCreateBean方法内部是创建一个Bean的具体流程,下一篇将详细介绍。

调用链详解:

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值