初识ApplicationContext、BeanFactory、BeanDefinitionRegistryPostProcessor、BeanFactoryPostProcessor、BeanDefinition、BeanPostProcessor对象。认识Spring中上述对象,可以对Spring框架有一个总体的认识。
ApplicationContext
ApplicationContext是Spring的上下文对象,就是我们常说的Spring容器。ApplicationContext是一个接口,我们常用其实现类ClassPathXmlApplicationContext和AnnotationConfigApplicationContext。如下代码块,其区别为一个使用注解,一个使用xml文件配置。ApplicationContext实现类中有一个重要的属性,就是BeanFactory。
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class);
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
BeanFactory
BeanFactory被称为bean工厂,负责Spring容器中所有对象的实例化和管理。Spring中默认使用的是其实现类DefaultListableBeanFactory。我们定义的类能在Spring容器启动时被实例化,都是这个工厂在起作用,使用的就是大名鼎鼎getBean方法。以AnnotationConfigApplicationContext为例,其中的BeanFactory在其父类GenericApplicationContext的构造方法中赋值。BeanFactory中有三个集合,分别包含BeanDefinitionRegistryPostProcessor、BeanFactoryPostProcessor、BeanDefinition、BeanPostProcessor对象。
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
BeanDefinition
普通java程序中,想要实例化一个类,必须要有该类的JavaBean。同理,在Spring中,想要实例化一个类,必须要有该类的BeanDefinition对象。BeanDefinition是Spring容器对JavaBean的封装,里面有JavaBean的类信息,其中部分属性如下图所示。其中beanClass对应BeanDefinition中的.class对象,propertyValues对应类中的属性值。
BeanPostProcessor
BeanPostProcessor是Spring框架中的拓展点,其作用是在每个bean实例化的不同阶段,对该bean执行一些操作。类似于拦截器原理,每个bean在实例化时都会被拦截,进而执行一些动作。BeanPostProcessor中有两个方法postProcessBeforeInitialization(Object bean, String beanName)和postProcessAfterInitialization(Object bean, String beanName),分别在bean实例化之前和实例化之后对bean做一些操作,默认实现表示什么都不做,直接返回bean,相当于拦截器直接放行。实现BeanPostProcessor的类会提前被实例化放入BeanFactory中,以便在实例化SpringBean时进行调用。
BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor
BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor是父子关系,BeanFactoryPostProcessor是BeanDefinitionRegistryPostProcessor的父类,两个接口的调用时序为先调用BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)方法,然后调用父类和子类的postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)方法。由方法名可以看出,两个方法分别针对BeanDefinition对象和BeanFactory对象操作。实现 BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor的类也会提前被实例化进行调用。
联系
Spring容器启动,首先创建ApplicationContext对象,创建ApplicationContext对象时,首先创建一个BeanFactory工厂,然后调用所有BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)方法(该类已经被提前实例化),该方法主要是通过注册器对象BeanDefinitionRegistry registry向容器中注册BeanDefinition对象,有了BeanDefinition对象就可被Spring容器实例化并进行管理。其次,调用所有BeanFactoryPostProcessor的postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)方法(该类已经被提前实例化),该方法主要是通过工厂对象ConfigurableListableBeanFactory beanFactory对工厂做一些设置,例如设置循环依赖等。经过前面的过程,所有被Spring容器扫描到的类都变成了BeanDefinition对象,存放在BeanFactory中,然后通过循环实例化,BeanDefinition对象变成SpringBean,在从BeanDefinition变成SpringBean的过程中,有各种BeanPostProcessor被调用,对SpringBean进行处理,例如生成代理、依赖注入等。当所有的SpringBean全部实例化完毕,ApplicationContext对象便实例化完成。Spring容器启动成功。
总结
以上只是Spring容器启动的大致流程,其中还有各种细节,比如,如何扫描、如何实例化、如何处理注解、如何注入、如何生成代理等等。