BeanFactory和ApplicationContext
BeanFactory是Spring的一个顶层接口,采用了简单工厂模式,通过BeanDefinition可以生产Bean,我们可以向BeanFactory注册BeanDefinition,之后通过getBean方法就可以生成对应的Bean。
ApplicationContext是BeanFactory,所以也有生产Bean的能力,相对于BeanFactory,ApplicationContext更加面向开发者,提供配置文件解析,自动装配,国际化,事件、扩展点等功能。
以下是AnnotatedBeanDefinitionReader的继承图,可以看出两者的关系:
ApplicationContext提供了更多的功能,BeanFactory能做的事情,ApplicationContext都可以做。而BeanFactory用到内存更少,更适合在穿戴设备上进行使用。
IOC加载Bean过程
BeanDefinition
BeanDefinition也是Spring的一个顶层接口,BeanFactory是按照BeanDefinition提供的关于Bean的信息来生成Bean的,ApplicationContext无论是从XML配置还是通过扫描注解等方式得到Bean的信息最后都要封装成为BeanDefinition的实现类,BeanDefinition的抽象子类AbstractBeanDefinition的部分属性如下:
private volatile Object beanClass; //bean名称
private String scope = SCOPE_DEFAULT; //作用域
private Boolean lazyInit; //是否懒加载
private String factoryBeanName; //工厂名
private String factoryMethodName; //工厂方法名
private String initMethodName; //初始化方法
private String destroyMethodName; //销毁方法
...
BeanDefinitionRegistry、BeanDefinitionScanner和BeanDefinitionReader
BeanFactory中有一个存储BeanDefinition的Map,不同ApplicationContext的目标都是一致的,将Bean的相关信息从配置文件或者其他地方解析成BeanDefinition,再注册到这个Map中,而这个过程就是有BeanDefinitionRegistry、BeanDefinitionScanner和BeanDefinitionReader三个组件配合完成,接下来以解析XML配置文件的方式举例说明各个组件的作用。
- BeanDefinitionReader:该组件负责从硬盘中加载XML配置文件,并解析各个标签。
- BeanDefinitionScanner:如果配置文件配置了扫描包的路径,扫描工作就由BeanDefinitionScanner来完成。
- BeanDefinitionRegistry:把前两个组件封装的BeanDefinition注册到Map中。
Bean生命周期
- 实例化:通过BeanDefinition中的bean的Class对象,进行反射或者工厂方法生成Bean对象。
- 属性注入:根据@AutoWired,@Value注解注入属性,其中会涉及循环依赖的问题,Spring通过三级缓存来解决循环依赖等问题。
- 初始化:调用initMethod,destroyMethod,穿插执行各种Aware接口。
整个生命周期还穿插着很多扩展点的执行。
扩展点
Spring提供了三种类型的扩展点,通过实现这些扩展点开发者可以介入到Spring的IOC的加载流程以及Bean的生命周期中。图中灰色组件就是扩展点
- BeanFactoryPostProcessor:实现该扩展点,可以获得并修改BeanDefinitionMap中已经存在BeanDefinition。
- BeanDefinitionRegistryPostProcessor:实现该扩展点,可以往BeanDefinitionMap注入BeanDefinition,该扩展点是BeanFactoryPostProcessor的子接口。
利用这两个扩展点很容易就可以实现Spring集成其他框架的操作,向Spring集成Mybatis就是利用这两个扩展点来做的。 - BeanPostProcessor:该扩展点贯穿一整个Bean的生命周期,无论是在实例化前后,属性注入前后,初始化前后都可以插入这个扩展点,以此来控制Spring Bean的生命周期。
在初始化之后,Spring也会调用该扩展点的子类BeanNameAutoProxyCreator来创建代理,实现AOP的功能。