spring学习(五)——Bean的创建(总结)

参考文章:

http://www.iocoder.cn/

根据前面几章学习,大概可以总结Bean创建的流程

  1. 启动方法
  2. 实例化
  3. 属性填充
  4. 初始化实例

bean 的初始化节点的启动方法,第一次调用 getBean()来开启

public Object getBean(String name) throws BeansException {
    return doGetBean(name, null, null, false);
}

 

spring内部调用doGetBean方法,其内部流程为

  1. 转换beanName,因为我们传入的 name 并不一定就是 beanName,可以传入 aliasName,FactoryBean
  2. 从缓存中加载单例bean
  3. bean实例化
  4. 原型模式的依赖检查,对于非单例模式的循环依赖spring无法解决
  5. 尝试从parentBeanFactory获取bean实例。
  6. 获取RootBeanDefinition并对其进行合并检查,从缓存中获取已经解析的RootBeanDefinition,如果父类不为null的话,会合并父类属性
  7. 依赖检查,解决bean之间的依赖关系
  8. 对不同的scope进行处理
  9. 如果类型参数传递不为空,进行类型转换处理

 

概括性的流程描述为:

  1. 从缓存中获取 bean
  2. 创建 bean 实例对象
  3. 从 bean 实例中获取对象

从缓存中获取bean

调用 #getSingleton(String beanName) 方法,从缓存中获取 singleton bean

spring对bean的分类singleton、prototype 和 其他(request、session、global session)

  • singleton:在spring的ioc容器中只存在一个对象实例,所有该对象的引用都共享这个实例,Spring 容器只会创建该 bean 定义的唯一实例,这个实例会被保存到缓存中。
  • prototype :每次对该bean的请求都会创建一个新的实例。
  • request:每次 http 请求将会有各自的 bean 实例。
  • session:在一个 http session 中,一个 bean 定义对应一个 bean 实例。
  • global session:在一个全局的 http session 中,一个 bean 定义对应一个 bean 实例。
public Object getSingleton(String beanName) {
    return getSingleton(beanName, true);
}

该方法就是从 singletonObjectsearlySingletonObjects、 singletonFactories 三个缓存中获取

 

创建bean实例对象

如果缓存中没有,也没有 parentBeanFactory ,则会调用 #createBean(String beanName, RootBeanDefinition mbd, Object[] args) 方法

protected abstract Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException;

该抽象方法的默认实现是在类 AbstractAutowireCapableBeanFactory 中实现,该方法其实只是做一些检查和验证工作,真正的初始化工作是由 #doCreateBean 方法来实现:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
        throws BeanCreationException

 

实例化 bean

如果缓存中没有 BeanWrapper 实例对象或者该 bean 不是 singleton,则调用 #createBeanInstance(...) 方法。创建 bean 实例。该方法主要是根据参数 BeanDefinition、args[] 来调用构造函数实例化 bean 对象

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)

属性填充

属性填充其实就是将 BeanDefinition 的属性值赋值给 BeanWrapper 实例对象的过程。在填充的过程需要根据注入的类型不同来区分是根据类型注入还是名字注入,当然在这个过程还会涉及循环依赖的问题的。

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) 

初始化bean

主要执行三个内容

  •  激活 Aware 方法。
  • 后置处理器的应用。
  • 激活自定义的 init 方法。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd)

从bean实例中获取对象

无论是从单例缓存中获取的 bean 实例 还是通过 #createBean(...) 方法来创建的 bean 实例,最终都会调用 #getObjectForBeanInstance(...) 方法来根据传入的 bean 实例获取对象,而其主要做一些检查工作,真正实现逻辑在#getObjectFromFactoryBean(...)里面

protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大·风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值