Spring Bean 创建过程

0. 通常,无论是DispatcherServlet、ContextLoaderListener还是ClassPathXmlApplicationContext,首次实例化bean的入口并不是在每次调用getBean的时候,而是在DefaultListableBeanFactory类的preInstantiateSingletons方法中:当配置文件加载完毕后,会预先将 非abstract、非延迟加载(lazy-init=false)的单例类 通过AbstractBeanFactory的getBean方法初始化到Spring容器中备用

1. 无论是哪个getBean方法的重载,终于都会归结到doGetBean方法的调用

2. 首先,doGetBean方法会将传入的String型的name参数格式化成Spring容器所采用的beanName,格式化主要有两点:一是将Spring框架类(如各种BeanFactory等)自带的前缀去掉,二是将使用了别名(alias)的bean的别名转换成真名

3. bean在Spring中的单例定义对象(sharedInstance)在Spring容器中是存放在一个名叫singletonObjects的ConcurrentHashMap中,根据格式化后的beanName去获取sharedInstance(这一过程中可能该sharedInstance正在创建中,此种情况下将返回该sharedInstance的一个早期引用)

4. 判断sharedInstance是否存在:

4.1. 若sharedInstance存在,则直接利用它来调用getObjectForBeanInstance

4.2.1. 若不存在,则从尝试从父BeanFactory中获取bean

4.2.2. 若从父BeanFactory中获取失败,则先通过beanName获取到bean的定义对象mbd,然后优先实例化从mbd中获取到的该bean所依赖的其它bean

4.2.2.1. 若mbd中定义该bean为singleton,则创建该bean的sharedInstance(真正创建sharedInstance的过程实际是调用ObjectFactory接口的createBean方法,由AbstractAutowireCapableBeanFactory类实现)

4.2.2.2. 若定义为prototype,则创建一个scopedInstance替代sharedInstance

4.2.3. 创建完成后也是调用getObjectForBeanInstance进入下一步

5.1. getObjectForBeanInstance方法首先判断传入的beanInstance(sharedInstance或scopedInstance)是否是一个工厂类的间接引用但同时它又不是一个工厂类(true则抛异常)

5.2. 若不是工厂类,或者是工厂类的一个间接引用,则直接返回该beanInstance

5.3. 若beanInstance是工厂类,则通过该工厂类生成真正的实例,并返回

6. 若最早传入的参数中有指定Class<?>,则进行类型强制转换,否则直接返回实例

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值