【Spring】IOC容器

IOC容器

BeanFactory 简单容器系列

BeanFactory定义了最基本的获取bean信息的功能,后续接口继承并扩展,增加了父容器管理、bean后置处理功能等。

«interface»
BeanFactory
«interface»
HierarchicalBeanFactory
«interface»
ConfigurableBeanFactory
«interface»
ListableBeanFactory
«interface»
AutowireCapableBeanFactory
«interface»
ConfigurableListableBeanFactory
DefaultListableBeanFactory
«interface»
BeanDefinitionRegistry

ApplicationContext 高级容器系列

ApplicationContext继承了BeanFactory接口体系中的HierarchicalBeanFactory接口、ListableBeanFactory接口;除此之外还继承了其他的接口:MessageSourceEnvironmentCapableApplicationEventPublisherResourceLoader等,丰富了容器的特性。

«interface»
BeanFactory
«interface»
HierarchicalBeanFactory
«interface»
ListableBeanFactory
«interface»
ApplicationContext
«interface»
MessageSource
«interface»
EnvironmentCapable
«interface»
ApplicationEventPublisher
«interface»
ResourceLoader
«interface»
ResourcePatternResolver
«interface»
WebApplicationContext
«interface»
ConfigurableApplicationContext

IOC容器启动过程

加载配置元数据,解析为BeanDefinitionBeanDefinition保存了bean的定义信息),beanDefinition注册到BeanDefinitionRegistry,启动过程完成,后续进行bean的实例化。

依赖注入

两种注入方式

(1)构造器注入

(2)setter方法注入

bean生命周期

处理aware接口
BeanFactoryAware#setBeanFactory
BeanNameAware#setBeanName
ApplicationContextAware#setApplicationContext
容器启动
实例化
注入对象属性
BeanPostProcessor#postProcessBeforeInitialization
初始化
BeanPostProcessor#postProcessAfterInitialization
销毁

Spring bean 循环依赖

循环依赖
A
B
A
B
C

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);
}

执行过程

  1. 先从一级缓存获取对象,获取到直接返回

  2. 如果一级缓存没有获取到对象,并且当前对象正在创建中,尝试从二级缓存获取,获取到即返回

  3. 如果二级缓存没有获取到对象,尝试从三级缓存获取

创建bean执行过程

一级缓存
二级缓存
三级缓存
存放二级缓存
存放三级缓存
获取A
将初始化的beanB放到一级缓存
将初始化的beanA放到一级缓存
A的代理对象
A对象的代理工厂
通过工厂获取到A的代理对象
A实例化
注入属性B
A初始化
清除二级缓存
B实例化
移除三级缓存中A对象的的工厂
B完成属性A注入
完成初始化

相关代码方法

//主要方法 创建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会生成多个代理对象,为了避免这种重复创建代理对象,把代理对象缓存下来,放到二级缓存,这样,下次再需要时,直接从二级缓存获取即可。

完结撒花~~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值