Spring源码学习笔记-bean加载

1、总体流程

在这里插入图片描述

2、转换对应的beanName

由于入参name不一定就是beanName,所以需要转换一下;
主要有如下转换内容:

2.1、去除FactoryBean修饰符‘&’

获取bean是通过FactoryBean.getObject();
name = “&nane”表示获取对应的FactoryBean本身;
而name="nane"表示获取获取nane对应的bean;即FactoryBean.getObject(); 方法的返回;

2.2、别名转为beanName

因为用户传入的name有可能是别名,则需要转换为对应的beanName;

2.3、补充点

spring中的Bean的id和name的区别
id和name都是spring 容器中中bean 的唯一标识符。
id: 一个bean的唯一标识 , 命名格式必须符合XML ID属性的命名规范
name: 可以用特殊字符,并且一个bean可以用多个名称:name=“bean1,bean2,bean3” ,用逗号或者分号或者空格隔开。如果没有id,则name的第一个名称默认是id

对于没有指定id、name属性的bean:
如果 一个 bean 标签未指定 id、name 属性,则 spring容器会给其一个默认的id,值为其类全名
如果有多个bean 标签未指定 id、name 属性,则spring容器会按照其出现的次序,分别给其指定 id 值为 “类全名#1”, “类全名#2”

3、从缓存中获取单例

在这里插入图片描述
singletonObjects: 用于保存beanName和创建bean实例之间的对应关系;
singletonFactories: 用于保存beanName和创建bean的工厂之间的关系;
earlySingletonObjects: 用于保存beanName和创建bean实例之间的对应关系;和singletonObjects区别在于:当一个单例bean放入后,那么bean还在被创建的过程中就可以通过getBean方法获取到,主要用来 检测循环引用
registeredSingletons: 用于保存当前所有已注册的bean。

4、加载单例

bean创建时,如果scope是单例,则有单独的加载单例方法;流程如下
在这里插入图片描述

5、创建bean前的准备

在这里插入图片描述

5.1、lookup-method

获取器注入是一种特殊的方法注入,它把一个方法声明为返回类型的bean,但具体返回那个bean需在配置文件中配置。
此方法是一种可插拔的方式,解除程序一来。
在这里插入图片描述

5.2、replaced-method

方法替换:可以在运行是用新的方法替换现有的方法。
在这里插入图片描述
接口MethodReplacer的方法reimplement入参解释:产生的代理对象(即myBeanReplacer);替换的方法对象(即oldMethod方法);替换的方法传入的参数(即oldMethod方法的入参)

5.3、实例化前置处理

短路判断:当经过前置处理后返回的结果如果不为空,则会直接返回结果。
实例化前的后处理器:给之类一个修改beanDefinition的机会,因为bean可能已经被处理成一个代理bean。
实例化后的后处理器:总体流程图中有提示。

6、循环依赖

循环依赖就是循环引用,两个或多个bean相互之间的持有对方,形成一个环。
循环调用不是循环依赖,它是方法之间的环调用,是无法解决的,除非有终结条件(递归);否则就是死循环,最终导致内存溢出错误。

6.1、构造器循环依赖

通过构造器注入构成的循环依赖,此依赖是无法解决的,只能抛出异常BeanCurrentLyInCreationException。
在这里插入图片描述

6.2、setter循环依赖

通过setter注入方式构成的循环依赖。
spring通过提前暴露刚完成的构造注入但未完成其他步骤(如setter注入)的bean来完成的,但只能解决单例作用域的bean循环依赖。
大致步骤:
1、myBeanA首先根据无参构造器创建bean,并暴露一个“ObjectFactory”用于返回一个提前暴露一个创建中的bean,并将myBeanA标识符放到“当前创建的bean池”中;接着进行setter注入myBeanB;

2、myBeanB的创建如myBeanA;

3、myBeanC前面步骤同myBeanA、myBeanB;在最后setter注入的时候,由于myBeanA已经提前暴露了“ObjectFactory”,所以返回了一个创建中的myBeanA;

4、最后在依赖注入myBeanB和myBeanA,完成setter注入。

6.3、prototype范围的依赖处理

因为spring容器不进行缓存“prototype”作用域的bean,所欲无法提前暴露一个创建中的bean;也就无法完成依赖注入。

7、bean创建

在这里插入图片描述

8、几个概念比较

8.1、BeanFactory和FactoryBean的区别

BeanFactory是个Factory,也就是IOC容器或对象工厂;提供了OC容器最基本的形式,给具体的IOC容器的实现提供了规范。

FactoryBean是个Bean,能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似。

8.2、BeanFactory和ApplicationContext的区别

BeanFacotry是spring中比较原始的Factory;
ApplicationContext接口,它由BeanFactory接口派生而来, 一种更向面向框架的方式工作以及对上下文进行分层和实现继承;提供了一些功能:国际化,资源访问,事件传播;载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值