将回答以下问题:
- BeanFactory 和 ApplicationContext 之间的关系和区别。
- 一个 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
andorg.springframework.context
packages are the basis for Spring Framework’s IoC container. Theinterface provides an advanced configuration mechanism capable of managing any type of object.
BeanFactory
is a sub-interface of
ApplicationContext
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 theApplicationContext
adds more enterprise-specific functionality. TheApplicationContext
is a complete superset of theBeanFactory
and is used exclusively in this chapter in descriptions of Spring’s IoC container. For more information on using theBeanFactory
instead of theApplicationContext,
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)