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层。