Spring IOC 源码解读

将回答以下问题:

  1. BeanFactory 和 ApplicationContext 之间的关系和区别。
  2. 一个 Bean 是如何被注入到 IOC 容器里,中间经历了什么过程(Bean 的生命周期)。

先入为主

假设你已经有如下经验:

  • 什么是 IOC。
don‘t call us, we‘ll call you - 好莱坞原则
  • 依赖查找和依赖注入。
依赖查找是 IOC 容器中的对象通过容器提供的 API 主动获取依赖对象
依赖注入是 IOC 容器将依赖对象直接注入到被依赖对象中
都是 IOC 容器实现的方式
  • Spring framework 的使用经验。

源码版本

5.3.8

涉及到的 Spring 模块

  • spring-context
  • spring-bean
  • spring-core

ApplicationContext 和 BeanFactory

 https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-introduction

The org.springframework.beans and org.springframework.context packages are the basis for Spring Framework’s IoC container. The BeanFactory interface provides an advanced configuration mechanism capable of managing any type of object. ApplicationContext is a sub-interface of BeanFactory. It adds:

  • Easier integration with Spring’s AOP features
  • Message resource handling (for use in internationalization)
  • Event publication
  • Application-layer specific contexts such as the WebApplicationContext for use in web applications.

In short, the BeanFactory provides the configuration framework and basic functionality, and the ApplicationContext adds more enterprise-specific functionality. The ApplicationContext is a complete superset of the BeanFactory and is used exclusively in this chapter in descriptions of Spring’s IoC container. For more information on using the BeanFactory instead of the ApplicationContext, see The BeanFactory.

  • 两者都是 IOC容器。
  • ApplicationContext 继承自 BeanFactory,同时内部还组合了一个 BeanFactory 的实现(DefaultListableBeanFactory)。
org.springframework.context.support.AbstractApplicationContext#getBeanFactory

  • BeanFactory 提供了最基础的 IOC 容器功能,例如:依赖查找。
  • ApplicationContext 是 BeanFactory 的超集,除了拥有 BeanFactory 的能力之外,还提供:
    • AOP
    • 资源管理
    • 国际化
    • 事件
    • Environment 抽象
  • BeanFactory 只会在查找 Bean 时才去创建(实例化,初始化)Bean,ApplicationContext 在启动时就已经创建好所有的 Bean。
org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization

Bean 生命周期

1. 启动 spring 应用上下文

org.springframework.context.support.ClassPathXmlApplicationContext

AbstractApplicationContext#refresh

  • 创建并初始化一个内部的 BeanFactory(DefaultListableBeanFactory)
  • AbstractRefreshableApplicationContext#refreshBeanFactory

2. 加载Bean元信息

Bean 定义中的 id,name,scope,primary 等统称为 Bean 元信息
org.springframework.beans.factory.config.BeanDefinition

AbStractXmlApplicationContext#loadBeanDefinitions

AbstractBeanDefinitionReader#loadBeanDefinitions

XmlBeanDefinitionReader#loadBeanDefinitions

2.1 解析 BeanDefinition

DefaultBeanDefinitionDocumentReader#parseBeanDefinitions

DefaultBeanDefinitionDocumentReader#processBeanDefinition

解析 xml 构建 BeanDefinitionHolder

BeanDefinitionHolder 包含 beanName,aliaes,BeanDefinition

默认 beanName = id。如果没有指定 id,容器会为 Bean 创建一个唯一的 beanName

问题:容器创建的唯一的 beanName 的规则是怎样的。

org.springframework.beans.factory.support.DefaultBeanNameGenerator#generateBeanName

2.2 注册 BeanDefinition 到 BeanFactory

DefaultListableBeanFactory#registerBeanDefinition

beanDefinitionMap(ConcurrentHashMap) 维护 BeanName 和 BeanDefinition 的对应关系

beanDefinitionNames(ArrayList) 保证 Bean 注册的顺序

2.3 合并 BeanDefinition

AbstractBeanFactory#getMergedLocalBeanDefinition

继承配置

最终所有的 BeanDefinition 都会被构建成 RootBeanDefinition

3. Bean 实例化

AbstractApplicationContext#finishBeanFactoryInitialization

DefaultListableBeanFactory#preInstantiateSingletons

AbstractBeanFactory#getBean

DefaultSingletonBeanRegistry#getSingleton

AbstractAutowireCapableBeanFactory#createBean

3.1 Bean Class 加载

AbstractBeanFactory#resolveBeanClass

AbstactBeanDefinition#resolveBeanClass

BeanDefinition 中的 beanClass(Object) 是以 String 定义,通过 spring 的 ClassUtil.forName 处理成 Class 类型,并通过 ClassLoader 加载

3.2 实例化前阶段

AbstractAutowireCapableBeanFactory#createBean

AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation

如果实现并注册了 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 会触发回调

3.3 实例化阶段

AbstractAutowireCapableBeanFactory#doCreateBean

AbstractAutowireCapableBeanFactory#createBeanInstance

  • 如果 BeanDefinition 中指定了工厂方法(factory-method) 则通过工厂方法AbstractAutowireCapableBeanFactory#instantiateUsingFactoryMethod
  • 如果 SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors 指定了构造器,或 BeanDefinition 中的 autowire-mode 为 constructor,或 BeanDefinition 中指定了构造参数(constructor-arg),或 BeanFactory#getBean 方法传了构造参数。则通过 AbstractAutowireCapableBeanFactory#autowireConstructor
  • 默认使用无参构造器,创建的实例会被包装成 BeanWrapper,BeanWrapper 中的 wrappedObject 就是最终会被注入到 IOC 容器中的 Bean。

问题:autowire-mode = constructor 时,构造器中的构造参数的注入是 byType ,还是byName。

DefaultListableBeanFactory#doResolveDependency

DefaultListableBeanFactory#determineAutowireCandidate

注意是否有 primary = ture 的 Bean

3.4 实例化后阶段

AbstractAutowireCapableBeanFactory#populateBean

如果实现并注册了 InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation 会触发回调

此时 Bean 已经完成实例化,但是并未填充属性

4. Bean 属性填充

BeanDefinition 中包含 Bean 的属性列表(org.springframework.beans.PropertyValues)
Bean 的属性会被构建成 org.springframework.beans.PropertyValue

AbstractAutowireCapableBeanFactory#populateBean

4.1 填充前阶段

如果实现并注册了 InstantiationAwareBeanPostProcessor#postProcessProperties 会触发回调

此阶段可以对 PropertyValue 做修改

4.2 构建属性描述

java.beans.PropertyDescriptor

包含属性的读方法引用(readMethodRef,通常是getter),写方法引用(writeMethodRef,通常是setter)等信息

AbstractAutowireCapableBeanFactory#filterPropertyDescriptorsForDependencyCheck

BeanWrapper#getPropertyDescriptors

java.beans.Introspector#getTargetPropertyInfo

过滤出所有有读方法和写方法的属性。

构建完成的 PropertyDescriptor 会作为 BeanWrapper 的属性。

4.3 填充属性值

AbstractAutowireCapableBeanFactory#applyPropertyValues

4.3.1 属性值类型转换

  • BeanDefinitionValueResolver#resolveValueIfNecessary,获取 BeanDefinition 中定义的属性值。
  • AbstractAutowireCapableBeanFactory#convertForPropertyBeanWrapperImpl#convertForProperty
  • 根据 PropertyDescriptor 中的读方法引用和写方法引用,通过反射获取转换目标类型,目标类型会被构建成 org.springframework.core.convert.TypeDescriptor。
  • 经过转换后的属性值,会记录在 PropertyDescriptor 的 convertedValue 属性中。

问题:获取到的转换目标类型是 getter 的返回类型,还是 setter 的参数类型。

org.springframework.core.convert.Property#resolveMethodParameter

4.3.2 调用 Bean 属性的 writeMethod 赋值

org.springframework.beans.BeanWrapperImpl.BeanPropertyHandler#setValue

5. Bean 初始化

AbstractAutowireCapableBeanFactory#initializeBean

5.1 初始化前阶段

Aware 接口回调

org.springframework.beans.factory.BeanNameAware

org.springframework.beans.factory.BeanClassLoaderAware

org.springframework.beans.factory.BeanFactoryAware

org.springframework.context.EnvironmentAware

org.springframework.context.EmbeddedValueResolverAware

org.springframework.context.ResourceLoaderAware

org.springframework.context.ApplicationEventPublisherAware

org.springframework.context.MessageSourceAware

org.springframework.context.ApplicationContextAware

org.springframework.context.ApplicationStartupAware

AbstractAutowireCapableBeanFactory#invokeAwareMethods

AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization

如果实现并注册了 BeanPostProcessor#postProcessBeforeInitialization 会触发回调

5.2 初始化阶段

AbstractAutowireCapableBeanFactory#invokeInitMethods

  • 如果实现了 org.springframework.beans.factory.InitializingBean 接口,会回调 InitializingBean#afterPropertiesSet
  • 如果 BeanDefinition 中有自定义初始化方法(init-method),会回调自定义初始化方法

AbstractAutowireCapableBeanFactory#invokeCustomInitMethod

5.3 初始化后阶段

AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization

如果实现并注册了 BeanPostProcessor#postProcessAfterInitialization 会触发回调

6. 注册 Bean(singleton) 到 IOC 容器中

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#singletonObjects

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#registeredSingletons

DefaultSingletonBeanRegistry#addSingleton

问题:spring 是如何解决循环依赖问题。

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值