也是先来说一下容器内部的运行原理
当Spring启动的时候读取应用程序提供的bean配置信息并在Spring容器中生成一份相应的bean配置注册表,然后根据这张注册表去实例化bean,装配好bean之间的依赖关系之后,为上层提供准备就绪的运行环境,Spring提供一个配置文件描述bean和bean之间的依赖关系,利于java语言的反射功能实例化bean,并且建立bean之间的依赖关系。
Spring IOC支持的功能有:
- 依赖注入
- 依赖检查
- 自动装备
- 支持集合
- 指定初始化方法和销毁方法
- 支持回调方法
接下来再来说说Spring是如何设计容器的
先从两个SpringIOC容器的核心接口来说:BeanFactory和ApplicationContext
BeanFactory:Spring框架最核心的接口
它提供了IOC的各种配置的机制,包含了Bean的各种定义,便于实例化bean,建立了Bean之间的依赖关系,Bean生命周期的控制也是它负责的。
可以看出,BeanFactory是一个顶级接口。
在BeanFactory的基础上,又设计了一个更高级的接口,也就是ApplicationContext,是BeanFactory的子接口之一。
以二者比较来看,BeanFactory是Spring框架的基础设施,面向Spring,ApplicationContext面向使用Spring框架的开发者。
ApplicationContext的功能如下:
- BeanFactory:能够管理,装配Bean
- ResourcePatternResolver:能够加载资源文件
- MessageSource:能够实现国际化等功能
- ApplicationEventPublisher:能够注册监听器,实现监听机制。
然后再来说说getBean方法的代码逻辑
- 转换beanName
- 从缓存中加载实例
- 实例化Bean
- 检测parentBeanFactory
- 初始化依赖的Bean
- 创建Bean
- 检查Bean符合要求之后,将Bean进行返回
再来说说Spring方面的经典考题:
- SpringBean的五个作用域
Singleton:Spring的默认作用域,为每一个IOC容器创建唯一的Bean实例,所以适合有状态的Bean。
prototype:针对每个getBean请求,容器都会创建一个bean实例,所以适合无状态的Bean,所以创建prototype成本是很高的。
如果是web容器,则额外支持以下三种作用域:
request:会为每个Http请求创建一个Bean实例
session:会为每个session创建一个Bean实例
globalSession:会为每个全局Http Session 创建一个Bean实例,该作用域仅仅对Portlet有效。
- Spring Bean 的生命周期
结合前面所提到的,容器创建之后会解析,并且创建出来bean,Spring Bean的生命周期主要有创建和销毁:
首先是创建Bean:
- 实例化Bean对象,以及设置Bean属性
- 我们通过使用各种Aware接口,注入Bean对容器基础设施的依赖,让容器感知到Bean的存在。
- 紧接着调用BeanPostProcessor的前置初始化方法postProcessBeforeInitialization,主要是在Spring Bean完成初始化实例之后,添加一些自定义的处理逻辑。
- 如果实现InitializingBean.afterPropertiesSet,会针对自定义初始化的Bean去做一些自定义的事情。
- 之后定义Bean init,初始化Bean
- 调用BeanPostProcessor的后置初始化方法postProcessAfterInitialization,做一些Bean初始化实例之后的自定义工作,最后就成功创建了Bean
然后是销毁 Bean:
- 如果Bean实现了DisposableBean接口,就会调用destroy方法
- 如果配置了destroy-method属性,则会调用其配置的销毁方法。