参考文章:
根据前面几章学习,大概可以总结Bean创建的流程
bean 的初始化节点的启动方法,第一次调用 getBean()来开启
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
spring内部调用doGetBean方法,其内部流程为
- 转换beanName,因为我们传入的
name
并不一定就是 beanName,可以传入 aliasName,FactoryBean - 从缓存中加载单例bean
- bean实例化
- 原型模式的依赖检查,对于非单例模式的循环依赖spring无法解决
- 尝试从parentBeanFactory获取bean实例。
- 获取RootBeanDefinition并对其进行合并检查,从缓存中获取已经解析的RootBeanDefinition,如果父类不为null的话,会合并父类属性
- 依赖检查,解决bean之间的依赖关系
- 对不同的scope进行处理
- 如果类型参数传递不为空,进行类型转换处理
概括性的流程描述为:
- 从缓存中获取 bean
- 创建 bean 实例对象
- 从 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);
}
该方法就是从 singletonObjects
、earlySingletonObjects
、 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)