分析spring源码第五(二)篇:Spring中Bean的加载

本文继上篇继续讲解Spring中Bean的创建。先分析createBean()方法源码,包括解析Class、处理配置、应用后处理器等操作。接着阐述doCreateBean中的创建过程,如实例化、解决循环依赖、填充属性等。还介绍了创建bean实例、属性注入及初始化bean的具体流程。

继上篇详解Spring中Bean的加载(一),现在继续讲解bean的创建,先看看createBean()方法源码(该方法在AbstractAutowireCapableBeanFactory类中):

1efeea5c4740a492d5cbbc5eb1f227fe8dd.jpg

从createBean()方法源码可以看出主要做了以下操作:

  1. 根据设置的class属性或根据className来解析Class;

  2. 对覆盖进行标记并验证,在Spring配置中是存在lookup-mothod和replace-method的,这两个配置的加载其实就是将配置统一存放在BeanDefinition中的methodOverrides属性里,这个方法的操作也就是针对于这两个配置的;

  3. 应用初始化前的后处理器,最后创建bean。

    在createBean()方法里执行完resolveBeforeInstantiation方法后,如果创建了代理且不为空的话就直接返回,否则需要进行常规bean的创建,这个创建过程是在doCreateBean中完成的,跟进源码:63243318764d91d30bb2baeec7bca344d70.jpgb963c4d5e8914e29b7473bcf721000bdc24.jpg

上面源码完成的操作可以概括为以下几点:

  1. 开始是单例的话要先清除缓存;

  2. 实例化bean,将BeanDefinition转换为BeanWrapper;

  3. 使用MergedBeanDefinitionPostProcessor,Autowired注解就是通过此方法实现类型的预解析;

  4. 解决循环依赖问题;

  5. 填充属性,将属性填充到bean实例中;

  6. 注册DisposableBean;

  7. 创建完成并返回

接下来创建bean实例,看createBeanInstance()方法:

0446474631c47ff4eb989c57b2f7238f26a.jpg

可以看出如果在RootBeanDefinition中存在factoryMethodName属性,或者说配置文件中配置了factory-method,那么Spring会尝试使用instantiateUsingFactoryMethod(beanName, mbd, args)方法根据RootBeanDefinition中的配置生成bean实例。

再解析构造方法并进行实例化,Spring会根据参数及类型判断使用哪个构造方法再进行实例化。判断调用哪个构造方法的过程会采用缓存机制,如果已经解析过则不需要重复解析而是从RootBeanDefinition中的属性resolvedConstructorOrFactoryMethod缓存的值去取,不然则需要再次解析。

创建bean后接下来就进行属性注入,属性注入的操作在populateBean()方法中,跟进源码:

022dde1e58c554a830477e367df2b16bd02.jpg5da948f35215c71e18f636c6d3e404b1560.jpg

在populateBean方法的中的主要处理流程:

  1. InstantiationAwareBeanPostProcessor处理器的postProcessAfterInstantiation方法控制程序是否继续填充属性;

  2. 根据注入类型提取依赖的bean,并存入PropertyValues中;

  3. 应用InstantiationAwareBeanPostProcessor处理器的postProcessPropertyValues方法对属性在填充前再次处理,主要还是验证属性;

  4. 将所有PropertyValues中的属性填充到BeanWrapper中。

最后初始化bean

学过Spring的都知道bean配置时有一个init-method属性,这个属性的作用是在bean实例化前调用init-method指定的方法进行需要的实例化操作,现在就进入这个方法了;Spring中程序已经执行过bean的实例化,并且进行了属性的填充,而就在这时将会调用用户设定的初始化方法。

66ad20542aa7ecf5d318587825b89d8ec03.jpg

invokeInitMethods调用初始化方法

517baca8f5a8e66df43000f7ba006a508ed.jpg

最后加载完Bean并执行完初始化操作后,一个bean的加载基本就结束了。

转载于:https://my.oschina.net/u/3209651/blog/1935391

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值