前言
Spring中核心之一就是Spring容器(或者IoC容器),一切Spring bean都存储在Spring容器内
需要搞清楚:
- Bean容器
- Bean加载过程
Spring容器
IoC,控制反转使得我们不需要自己创建对象,而是由容器接管,让容器注入到我们需要的地方
这里就涉及到了Spring容器,Spring容器有两种:
- BeanFactory:较低级的容器,负责配置、创建、管理Bean
- ApplicationContext:较为高级的容器(应用上下文),是BeanFactory的子接口,在其基础上还管理着Bean和Bean之间的依赖关系、上下文信息
正如同它们的名字,BeanFactory,Bean的工厂,用于创建管理Bean , ApplicationContext,应用上下文,不在局限与Bean,而是拥有整个应用的信息
继承体系
- BeanFactory:bean容器的顶级接口,提供了getBean、getType、getAliases等方法
- HierarchicalBeanFactory:提供父容器的访问功能
getParentBeanFactory
ListableBeanFactory:提供了批量获取Bean、BeanName的方法Map<String, T> getBeansOfType(@Nullable Class<T> type)
等
AutowireCapableBeanFactory:在BeanFactory基础上实现对已存在实例的管理
这三个是BeanFactory的子接口
- 低级容器相关类:DefaultListableBeanFactory等,
DefaultListableBeanFactory是最主要的BeanFactory,实现了父BeanFactory所有功能,以Map的形式存储Bean,可以注册BeanDefinition(配置文件bean抽象为类)
- 高级容器:ApplicationContext,其主要的实现类:
ClassPathXmlApplicationContext:默认从类路径加载配置文件
FileSystemXmlApplicationContext:默认从文件系统中装载配置文件
AnnotationConfigApplicationContext:解析依赖注入的JavaConfig
ApplicationContext本质上也是BeanFactory,但不仅仅是Bean容器
BeanFactory与ApplicationContext区别
两种虽然都是Spring容器,但有很大的区别:
- BeanFactory只是Bean容器,支持Bean的配置、创建、管理,是Spring的基础,但BeanFactory是Spring中比较原始的Factory,它不支持AOP、Web等Spring插件
- ApplicationContext不仅仅是Bean容器
ApplicationContext继承了BeanFactory,但ApplicationContext不仅包含了BeanFactory的所有功能,还支持Spring的各种插件,
如国际化MessageResource接口,事件机制Event与Listener、底层资源访问ResourceLoader
还以一种面向框架的方式工作以及对上下文进行分层和实现继承。 - BeanFactory是Spring框架的基础设施,面向Spring本身;而ApplicationContext面向使用Spring的开发者,相比BeanFactory提供了更多面向实际应用的功能,几乎所有场合都可以直接使用ApplicationContext而不是底层的BeanFactory
BeanDefinition
A BeanDefinition describes a bean instance, which has property values,constructor argument values, and further information supplied by concrete implementations.
这是BeanDefinition的注释:一个BeanDefinition用于描述一个Bean实例,具体该实例的各种信息
BeanDefinition接口的子抽象类:
拥有许多字段用于描述一个Bean实例,这对应着一个Bean标签或者注解的各种子标签、属性
具体的由XML的bean标签到BeanDefinition是一个很复杂的过程:
Spring-BeanFactory基本工作流程
大致:
- BeanFactory在初始化时调用loadBeanDefinitions方法
- 我们使用的ApplicationContext获得url或者class,一步步调用找到bean对应的配置文件、类
- XmlBeanDefinitionReader调用doLoadDocument方法,读取xml文件的信息读取文件解析生成Document对象(Resource解析)
- 加载生成BeanDefinition
- beanDefinitionMap是IOC容器中实际存储Bean(BeanDefinition)的地方
内部有很多细节,详情看上面大佬的文章
总之,我们把bean标签的各种属性封装成了一个BeanDefinition,注册到了容器
PostProcessor
- BeanFactoryPostProcessor
bean工厂的bean属性处理容器,可以管理我们的bean工厂内所有的beandefinition数据,可以随心所欲的修改属性 - BeanPostProcessor
bean的属性处理器,即可以修改Bean的属性,操作Bean的实例化
这种处理Bean、BeanFactory的操作最典型的就是AOP
一个很复杂的面试题
Spring中Bean的生命周期:
- 开始初始化容器
- 加载BeanFactoryPostProcessor实现类
- 执行BeanFactoryPostProcessor的postProcessBeanFactory方法
- 加载BeanPostProcessor实现类
- 实例化业务bean
- Aware接口族调用
- 执行BeanPostProcessor实现类的postProcessBeforeInitialization方法
- 执行InitializingBean实现类的afterPropertiesSet方法
- 执行bean的init-method属性指定的初始化方法
- 执行BeanPostProcessor实现类的postProcessAfterInitialization方法
- 初始化完成
- 关闭容器,执行DiposibleBean实现类的destory执行bean的destroy-method属性指定的初始化方法
总结
大致看下来,Spring容器装配bean的过程:
- 初始化容器,加载后置处理器
- 通过设置的BeanFactory或ApplicationContext获得配置、类的路径
- 解析XML、注解配置, 获得对应的BeanDefinition,注册到beanDefinitionMap(容器)中
Spring源码太复杂了,暂时不是我能够看懂的