DI:依赖注入,在IOC容器完成了bean定义资源的定位、加载、解析注册之后,IOC容器已经管理了bean定义的相关数据,但是这个时候还没有发生依赖注入。
依赖注入发生的两个阶段:
1、用户第一次调用getBean()的时候
2、用户在bean的配置文件中配置了lazy-inint=false属性(禁止延迟加载)时候,会在bean解析注册的时候进行预实例化,触发依赖注入。
getBean入口:AbstractBeanFactory
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
1、先看看创建对象的缓存中是否有当前要创建的单例模式的bean,有则返回
2、否则看看缓存中有没有当前创建的原型模式的bean
循环依赖问题:
spring只会解决singleton(单例)模式下的通过setter方法注入的循环依赖问题:如下
首先,单例bean的依赖注入分为构造器注入和setter方法注入。Spring只会解决setter方法注入的循环依赖,构造器注入的循环依赖会抛BeanCurrentlyInCreationException异常。其次,Spring不会解决prototype作用域的bean,如果有循环依赖会抛BeanCurrentlyInCreationException异常
一级缓存:singletonObjects存放初始化好的bean(初始化:创建并设置属性值)
二级缓存:earlySingletonObjects存放已经创建出来了但是还没有完成初始化的bean,就是正在初始化的bean
三级缓存:singletonFactories存放创建bean的BeanFactory对象
依赖注入的两种方式:构造器;setter方法。