IOC容器
BeanFactory 简单容器系列
BeanFactory
定义了最基本的获取bean信息的功能,后续接口继承并扩展,增加了父容器管理、bean后置处理功能等。
ApplicationContext 高级容器系列
ApplicationContext
继承了BeanFactory
接口体系中的HierarchicalBeanFactory
接口、ListableBeanFactory
接口;除此之外还继承了其他的接口:MessageSource
、EnvironmentCapable
、ApplicationEventPublisher
、ResourceLoader
等,丰富了容器的特性。
IOC容器启动过程
加载配置元数据,解析为BeanDefinition
(BeanDefinition
保存了bean的定义信息),beanDefinition
注册到BeanDefinitionRegistry
,启动过程完成,后续进行bean的实例化。
依赖注入
两种注入方式
(1)构造器注入
(2)setter方法注入
bean生命周期
Spring bean 循环依赖
循环依赖
Spring
中使用三级缓存来解决循环依赖问题。
三级缓存
/**
* Cache of singleton objects: bean name --> bean instance
* 一级缓存,缓存了经历过整个bean生命周期的bean
*/
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);
/**
* Cache of singleton factories: bean name --> ObjectFactory
* 三级缓存,缓存了objectFactory,主要用来去生成原始对象进行了aop之后得到的代理对象
*/
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);
/**
* Cache of early singleton objects: bean name --> bean instance
* 二级缓存,缓存了实例化完成的原始对象,还没有执行属性填充以及后置处理器方法
*/
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
核心方法
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
执行过程
-
先从一级缓存获取对象,获取到直接返回
-
如果一级缓存没有获取到对象,并且当前对象正在创建中,尝试从二级缓存获取,获取到即返回
-
如果二级缓存没有获取到对象,尝试从三级缓存获取
创建bean
执行过程
相关代码方法
//主要方法 创建bean,方法内部有关于对循环依赖的处理
//creates a bean instance, populates the bean instance, applies post-processors, etc
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
{
//创建bean
createBean(String beanName, RootBeanDefinition mbd, Object[] args){
//实例化
createBeanInstance()
//如果当前创建的是单例bean,并且允许循环依赖,将objectFactory放入三级缓存
//singletonFactories{key:beanName,value:ObjectFactory}
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
//注入属性
populateBean(){
//尝试获取依赖的bean, 如果bean还没有实例化,走createBean
//从三级缓存拿到依赖的bean,放到二级缓存,将该依赖bean从三级缓存remove
beanFactory.getBean(beanName, requiredType);
};
//初始化,走完一个生命周期,bean放到一级缓存里
initializeBean()
}
为什么要有三级缓存?
一级缓存的作用,它是一个单例池,保证bean的单例属性
三级缓存,存放对象的代理工厂,它的作用就是存放半成本的单例bean;为什么不直接存这个半成本bean,而是存它的代理工厂,因为有AOP
- 如果 bean 有
AOP
,就创建一个代理对象; - 如果 bean 没有
AOP
,就返回原对象。
二级缓存,就是用来存放工厂生成的对象,这个对象可能是原对象,也可能是个代理对象。
为什么要有二级缓存?
如果 bean 需要进行AOP
,并且它又被多个其他的 bean 所依赖,那么每次被依赖注入时,bean会生成多个代理对象,为了避免这种重复创建代理对象,把代理对象缓存下来,放到二级缓存,这样,下次再需要时,直接从二级缓存获取即可。
完结撒花~~