关于spring:spring加载机制及流程

41次阅读

共计 3977 个字符,预计需要花费 10 分钟才能阅读完成。

// 筹备工作,记录下容器的启动工夫、标记“已启动”状态、解决配置文件中的占位符
prepareRefresh();
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
 
// 设置 BeanFactory 的类加载器,增加几个 BeanPostProcessor,// 手动注册几个非凡的 bean, 类加载器,Aware 接口初始化解决类, 事件监听器等等
prepareBeanFactory(beanFactory);
 
// 这步比拟要害,解析注解和 xml 配置文件就会解析成一个个 Bean 定义,注册到 BeanFactory 中,// 当然,这里说的 Bean 还没有初始化,只是配置信息都提取进去了,// 注册也只是将这些信息都保留到了注册核心(说到底外围是一个 beanName-> beanDefinition 的 map)
postProcessBeanFactory(beanFactory);
 
// 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 回调办法
// 还有 BeanDefinitionRegistryPostProcessor 这个实现类,能够进行 bean 配置的注册
invokeBeanFactoryPostProcessors(beanFactory);  
 
// 注册 BeanPostProcessor 的实现类
// 此接口两个办法: postProcessBeforeInitialization 和 postProcessAfterInitialization
// 两个办法别离在 Bean 初始化之前和初始化之后失去执行。这里仅仅是注册,之后会看到回调这两办法的机会
registerBeanPostProcessors(beanFactory);
 
// 初始化以后 ApplicationContext 的 MessageSource,国际化
initMessageSource();
 
// 初始化以后 ApplicationContext 的事件播送器
initApplicationEventMulticaster();
 
// (钩子办法)具体的子类能够在这里初始化一些非凡的 Bean(在初始化 singleton beans 之前)onRefresh();
    
// 注册事件监听器,监听器须要实现 ApplicationListener 接口
registerListeners();
 
// 重点,重点,重点 初始化所有的 singleton beans(lazy-init 的除外)finishBeanFactoryInitialization(beanFactory);
{
    // 创立 bean, 并返回, 如果是一般 bean 间接返回, 如果是 factorybean, 返回创立的实例对象
    //prototype 原型 bean, 则抛异样
    getBean()->getSingleton()-> 获取单例缓存,判断
        -------------
            有则间接,getObjectForBeanInstance
        -------------
            没有则,判断是否已创立这个实例了,有了则抛异样,避免循环依赖
            而后 bean 获取进行了父类委托和缓存优化
            获取 BeanDefinition 的 dependsOn 依赖关系,首先加载所有依赖 getBean(),而后判断 bean 是 Singleton 还是 Prototype,--------------
                Singleton,1. 先锁定 singletonObjects,如果外面有对象间接返回,2. 否则先把以后 bean 退出到已创立的单例汇合里,再 createBean(),开释汇合里的记录,3. 最初增加进 singletonObjects,从 singletonFactories 和 earlySingletonObjects 里删除
            --------------
                Prototype,先把以后 bean 退出到已创立的多例汇合里,再 createBean(),开释汇合里的记录
            
    最初都须要调用 getObjectForBeanInstance()获取实例
        
    getSingleton():1. 取 singletonObjects 里的记录,有则间接返回,2. 取 earlySingletonObjects 里的记录,有则间接返回
        3. 如果是空的,则取 singletonFactories 里的 FactoryBean 对象,并从 singletonFactories 删除,退出 earlySingletonObjects
        
    createBean():1. 执行 InstantiationAwareBeanPostProcessor(Class<?> beanClass, String beanName)生命周期
            如果上一步返回的 bean 不为空,则调用 BeanPostProcessor 的 after 回调,并间接返回 bean 实例
        2. 否则继续执行 doCreateBean 办法,调用 createBeanInstance()生成 BeanWrapper 对象(提供 javabean 对象的属性填充接口等),执行 MergedBeanDefinitionPostProcessor(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName)的回调,3. 执行 SmartInstantiationAwareBeanPostProcessor(Object bean, String beanName)回调
        4. 如果不存在 singletonObjects 中,则把以后 bean 存入 singletonFactories,从 earlySingletonObjects 删除
        5. 执行 populateBean()
            autowireByName 和 autowireByType 注入所有依赖 getBean()
            执行 InstantiationAwareBeanPostProcessor(PropertyValues pvs, Object bean, String beanName)和
                (PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)回调
        6. 执行 initializeBean()
            执行 BeanPostProcessor 的 before(Object bean, String beanName)回调
            执行 afterPropertiesSet()回调
            执行 BeanPostProcessor 的 after(Object bean, String beanName)回调
        7. 注册 bean 敞开的生命周期回调
        
    getObjectForBeanInstance():1.factoryBeanObjectCache 里有记录则间接返回
        2. 没有则从 factorybean 里获取 object 并存入 factoryBeanObjectCache,而后返回
    
}
 
 
// 最初,播送事件,ApplicationContext 初始化实现,不开展
finishRefresh();

循环依赖问题

Spring 为了解决单例的循环依赖问题,addSingletonFactory 办法应用了三级缓存, 这三级缓存别离指:
singletonFactories:单例对象工厂的 cache 一级缓存:用于寄存齐全初始化好的 bean
earlySingletonObjects:提前暴光的单例对象的 Cache 二级缓存:寄存半成品的 Bean,半成品的 Bean 是已创建对象,然而未注入属性和初始化。用于解决循环依赖
singletonObjects:单例对象的 cache 三级级缓存:存的是 Bean 工厂对象,用来生成半成品的 Bean 并放入到二级缓存中。用于解决循环依赖

A 创立过程中须要 B,于是 A 将本人放到三级缓外面,去实例化 B
B 实例化的时候发现须要 A,于是 B 先查一级缓存,没有,再查二级缓存,还是没有,再查三级缓存,找到了!
而后把三级缓存外面的这个 A 放到二级缓存外面,并删除三级缓存外面的 A
B 顺利初始化结束,将本人放到一级缓存外面(此时 B 外面的 A 仍然是创立中状态)
而后回来接着创立 A,此时 B 曾经创立完结,间接从一级缓存外面拿到 B,而后实现创立,并将本人放到一级缓存外面

咱们能够晓得,Spring 解决循环依赖的窍门就在于 singletonFactories 这个三级 cache。这个 cache 的类型是 ObjectFactory。这里就是解决循环依赖的要害,产生在 createBeanInstance 之后,也就是说单例对象此时曾经被创立进去(调用了结构器)。这个对象曾经被生产进去了,尽管还不完满(还没有进行初始化的第二步和第三步),然而曾经能被人认出来了(依据对象援用能定位到堆中的对象),所以 Spring 此时将这个对象提前曝光进去让大家意识,让大家应用。

所以 spring 不反对结构器循环依赖和 prototype field 属性注入循环依赖
非单例 Bean 默认不会初始化

为什么采纳三级缓存而不是二级?

包装一层 ObjectFactory 对象不提前创立好代理对象,在呈现循环依赖被其余对象注入时,才实时生成代理对象。这样在没有循环依赖的状况下,Bean 就能够按着 Spring 设计准则的步骤来创立。执行一些生命周期办法回调。
Spring 容器会将每一个正在创立的 Bean 标识符放在一个“以后创立 Bean 池”中,Bean 标识符在创立过程中将始终放弃在这个池中,因而如果在创立 Bean 过程中发现自己曾经在“以后创立 Bean 池”里时将抛出 BeanCurrentlyInCreationException 异样示意循环依赖;而对于创立结束的 Bean 将从“以后创立 Bean 池”中革除掉。

正文完
 0