Spring Bean的加载

时间:2022-07-24
本文章向大家介绍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。