zoukankan      html  css  js  c++  java
  • Spring Bean的加载

    一、Spring加载bean的原则

    不等bean创建完成就会将创建bean的ObjectFactory提早曝光加入到缓存中。 

    单例bean在Spring容器里只会创建一次,后续创建时会首先从缓存中获取,尝试加载,不成功则从singletonFatories中加载。

    当存在循环依赖的时候,依据Spring的加载bean原则,下一个bean需要依赖上一个bean的时候直接使用ObjectFactory。

    缓存中保存的是bean的原始状态,需要进行bean的实例化操作。

    Spring初始化bean的时候,会首先初始化这个bean所对应的依赖。

    package org.springframework.beans.factory;
    
    /**
    * Interface to be implemented by objects used within a {@link BeanFactory}
    * which are themselves factories. If a bean implements this interface,
    * it is used as a factory for an object to expose, not directly as a bean
    * instance that will be exposed itself.
    */
    public interface FactoryBean<T> {
    
      /**
        * Return an instance (possibly shared or independent) of the object
        * managed by this factory.
        */
      T getObject() throws Exception;
    
      /**
        * Return the type of object that this FactoryBean creates,
        * or {@code null} if not known in advance.  
        */
      Class<?> getObjectType();
    
      /**
        * Is the object managed by this factory a singleton? That is,
        * will {@link #getObject()} always return the same object
        * (a reference that can be cached)?
        * 单例对象会放在Spring单例缓存池中
        */
      boolean isSingleton();
    
    }

    二、工厂方法配置bean

    <bean id="book" class="com.xxx.model.BookFactory"/>

    BookFactory实现了FactoryBean,则当使用getBean("book")时,返回FactoryBean#getObject()方法返回的对象,即FactoryBean#getObject()代理了getBean()方法:

    Book book = ctx.getBean("book");

    如果要获取BookFactoryBean对象,则需要使用前缀“&”,使用如下:

    BookFactory bookFactory = ctx.getBean("&book");

    三、单例Bean(singleton)获取

    singletonObjects<BeanName, BeanInstance>.get(beanName):Map单例缓存获取。synchronized(this.singletonObjects),全局变量同步。

            ↓↓

            ↓↓==Null

            ↓↓

    earlySingletonObjects<BeanName, BeanInstance> .get(beanName):处理循环引用依赖检测。

            ↓↓

            ↓↓==Null

            ↓↓

    singletonFactories<BeanName, BeanFactory> .get(beanName):调用相应单例创建工厂getObject()返回Bean对象。

            ↓↓

            -->earlySingletonObjects.put(beanName, singletonObject)存储获取的Bean实例。

            --> singletonFactories.remove(beanName)移除beanName对应单例工厂。

    四、Bean创建

    if singleton,清除缓存。

    实例化Bean(createBeanInstance),BeanDefinition=》BeanWrapper。

    使用工厂方法创建:RootBeanDefinition存在factoryMethodName,或配置了factory-method=》instantiateUsingFactoryMethod()

            ↓↓

            ↓↓<不存在>

            ↓↓

    根据参数选择相应的构造函数初始化

            ↓↓

            ↓↓<不存在>

            ↓↓

    默认构造函数实例化。

    MergeBeanDefinitionPostProcessor:合并后处理,注解处理位置。

    依赖处理。

    属性填充。

    循环依赖检查,Spring处理循环依赖只对singleton有效。

    注册DisposableBean,处理destroy-method。 

    完成创建。

    五、Bean初始化

    Aware方法,Post处理,Init处理。 

    Aware:注入相应资源。

    PostProcessor:预置处理。

    Init处理 :配置init-method或者继承InitializingBean#afterPropertiesSet()方法。afterPropertiesSet先于init-method。

  • 相关阅读:
    EF实现增删改查
    托管代码与非托管代码的区别
    堆、栈以及队列
    C#装箱和拆箱
    Leecode刷题之旅-C语言/python-349两个数组的交集
    Leecode刷题之旅-C语言/python-344反转字符串
    Leecode刷题之旅-C语言/python-217存在重复元素
    Leecode刷题之旅-C语言/python-206反转链表
    Leecode刷题之旅-C语言/python-204计数质数
    Leecode刷题之旅-C语言/python-203移除链表元素
  • 原文地址:https://www.cnblogs.com/niejunlei/p/6053478.html
Copyright © 2011-2022 走看看