spring框架中的BeanFactory和ApplicationContext是非常重要的俩个接口。
ApplicationContext是BeanFactory的子接口,BeanFactory是IOC容器,ApplicationContext是应用的上下文除了实现了BeanFactory还实现了配置文件的读取等操作。
所有的bean初始化都在ApplicationContext的refresh方法中完成。本文以AnnotationConfigApplicationContext为例。
继承关系图如下
BeanFactory
名字的直译是Bean工厂,我们定义的Bean在这里就行初始化。图中真正可以作为一个独立使用的IOC容器的是DefaultListableBeanFactory
BeanFactory主要的方法是getBean,用来获取Bean
3个子接口:
- HierarchicalBeanFactory:提供父容器的访问功能
- ListableBeanFactory:提供了批量获取Bean的方法
- AutowireCapableBeanFactory:在BeanFactory基础上实现对已存在实例的管理
1 | public interface HierarchicalBeanFactory extends BeanFactory { |
1 | //提供通过beanName、类型查找Bean的接口 |
1 | public interface AutowireCapableBeanFactory extends BeanFactory { |
AnnotationConfigApplicationContext
构造方法:我们以下面的构造方法为例
1 | public AnnotationConfigApplicationContext(String... basePackages) { |
this()做了什么
- 调用父类GenericApplicationContext的无参构造方法,在GenericApplicationContext中初始化DefaultListableBeanFactory
- 自己的构造方法初始化BeanDefinition的读取器和类扫描器
1 | public GenericApplicationContext() { |
scan or register
AnnotationConfigApplicationContext的构造方法一般支持俩种,注册某些Component注解、扫描某一个包,他们具体的区别就在构造方法中的register或者scan,俩者逻辑都差不多,这里我们
- scan(basePackages),它会调用scanner.scan(basePackages)。scan扫描的bean的注解默认只支持Commponent(以及他的子类),javax.annotation.ManagedBean,javax.inject.Named,如果有特殊的注解需要需要自己实现
register(componentClasses),他会调用reader.register(componentClasses)。register注册的bean可以不用加注解。
这一步实际上是对入参的basePackage或者class,进行扫描或者注册,生成BeanDefinition保存到容器中。BeanDefinition封装了Class的MetaInfo,包含了类名,属性,方法,父类信息等。便于后续根据的BeanDefinition对其包含的对象进行初始化。
我们来看下 //todo
refresh
真正bean的初始化过程。
1 |
|
下面我们一步步的看
prepareRefresh
为refresh做准备,设置Application的startUpdate,将状态改为active,同时初始化properties。
obtainFreshBeanFactory
重新刷新BeanFactrory,代码如下
1 | protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { |
这里的refreshBeanFactory()俩个实现,GenericApplicationContext和AbstractRefreshableApplicationContext
GenericApplicationContext对应的是本文的Annotation在ApplicationContext的构造方法中已经register/scan过,BeanDefinition了这里就不用创建beanfactroy在加载一遍bean了
1 |
|
AbstractRefreshableApplicationContext对应的是xml,file等方式,在构造方法中只是加载文件没有创建BeanDefinition,所在这里要创建BeanDefinition对象
1 |
|
prepareBeanFactory
设置beanFactory的classloader,spel表达式,bean的属性处理器,自动装配的例外/特殊规则,BeanProcessor,env等
1 | protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { |
postProcessBeanFactory
没有具体实现的空方法,在beanFactory都设置好以后,留给容器根据自己的使用场景自己定制如:web容器注入一些重要资源(类似Application的属性和ServletContext的属性),我们可以实现该方法。
1 | protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { |
invokeBeanFactoryPostProcessors(beanFactory)
容器执行内置的以及用户自定义的BeanDefinitionRegistryPostProcessor以及BeanFactoryPostProcessor的postProcessBeanFactory方法。
BeanDefinitionRegistryPostProcessor作用见链接Spring源码-BeanDefinitionRegistryPostProcessor
流程如下:
- invokeBeanFactoryPostProcessors调用PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()方法
- 执行容器注册好的BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry以及BeanFactoryPostProcessor.postBeanFactory,优先级是实现PriorityOrder接口,Order注解,其他
- BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry,见ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry,将Component,Import ImportResource Component注解的类解析Configuratuon
- 执行BeanFactoryPostProcessor.postBeanFactory。
1 | protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { |
registerBeanPostProcessors
注册执行BeanPostProcessors,这指是注册BeanPostProcessors,并没有执行
流程如下:
- registerBeanPostProcessors->PostProcessorRegistrationDelegate.registerBeanPostProcessors
- 在registerBeanPostProcessors取得所有的BeanPostProcessor
- 对BeanPostProcessors分组,分成:PriorityOrdered,Ordered,nonOrdered,internal(属于MergedBeanDefinitionPostProcessor)
- 对他们进行排序,注册顺序是PriorityOrdered->Ordered->nonOrdered->internal–>ApplicationListenerDetector
1 | public static void registerBeanPostProcessors( |
initMessageSource
【todo】暂时忽略
initApplicationEventMulticaster
【注册时间监听器】后续单独拿出一章讲。
这里,注册ApplicationEventMulticaster 默认 SimpleApplicationEventMulticaster
registerListeners
注册定义的ApplicationListener,注册容器的event和自定义的eventListener
1 | protected void registerListeners() { |
preInstantiateSingletons
对之前在AplicationContext构造方法中,scan或者register时候生成的BeanDefinition进行实例化,注意,这里只针对,单例、非延迟加载的BeanDefinition的实体化,具体方法在DefaultListableBeanFactory.preInstantiateSingletons中。见:Spring源码-BeanDefinition
1 |
|
finishRefresh
完成applicationContext的refresh,发送系统事件等
1 | protected void finishRefresh() { |