spring启动流程中的refresh阶段
beanFactory在refresh阶段完成配置、扫描bean、注册bean等重要操作步骤
- refresh代码流程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
...
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
...
// 获取beanFactory,默认为new DefaultListableBeanFactory()
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);// 配置beanFactory
try {
postProcessBeanFactory(beanFactory);// 交给context去配置beanFactory
invokeBeanFactoryPostProcessors(beanFactory);// 调用BeanFactoryPostProcessors
registerBeanPostProcessors(beanFactory);// 注册拦截bean创建的bean处理器
initMessageSource();
initApplicationEventMulticaster();// 初始化事件广播器,待会扫描以注解形式存在的listener
onRefresh(); // context容器进行onRefresh,servletContext会在这个时候创建tomcat
registerListeners();// 注册以注解形式存在的listener,并且广播之前已广播的事件
finishBeanFactoryInitialization(beanFactory); // 加载LoadTimeWeaverAware(增强AOP,通过修改字节码实现AOP,class已加载过的话则不起作用),冻结配置,初始化所有的bean(单例、notLazy)
/* 最后一步: 发布相对应的事件
1:获取所有Lifecycle类型的bean,如果是SmartLifecycle的类型并且isAutoStartup为true,则调用start方法
2:发布contextRefreshedEvent
3:把bean的信息注册到ManagementFactory(java监控工厂)
*/
finishRefresh();
} catch (BeansException ex) {
...
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
} finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
...
}
我们具体分析下refresh当中的重要操作步骤,分析之前,我们先了解beanFactory的作用以及实现都有哪些
beanFactory作用
实现的类结构,如图
1. BeanFactory
主要作用是通过名字或类型get对应的bean实例
getBean|isTypeMatch| getBeanProvider|getType|getAliases等方法
2. SingletonBeanRegistry
主要作用是注册单例的bean
registerSingleton|getSingleton|getSingletonNames等方法
3. HierarchicalBeanFactory
可分层的beanFactory主要作用是可以多个beanFactory并且有父子关系
getParentBeanFactory|containsLocalBean 只有两个方法
4. BeanDefinitionRegistry
registerBeanDefinition|removeBeanDefinition| getBeanDefinition|getBeanDefinitionNames等方法
- registerBeanDefinition
BeanDefinition是包含了bean的所有信息,bean的名称、bean的class、scope、isLazy、isPrimary、bean的属性和bean的依赖关系等
beanFactory获取一个bean时,除非bean已经存在,否则会通过beanDefinition自动创建,没有beanDefinition就会报错,所以beanDefinition是一个很重要的存在
BeanDefinition包含了class的各种信息如注解的信息、class的资源路径等,但是不会初始化class,主要通过ASM字节码读取器来解析class字节码的内容ASM解析class字节码默认实现类
SimpleMetadataReaderFactory
,由SharedMetadataReaderFactoryContextInitializer
在spring启动阶段中的context#initialize
注册
beanFactory通过调用BeanFactoryPostProcessor主要的实现ConfigurationClassPostProcessor先扫描所有的class,通过AMS既可以读取class内容也不会加载class,然后符合条件的bean会包装成BeanDefinition注册到beanFactory中
5. AliasRegistry
为注册bean的别名,通过别名也可以获取到bean,主要作用就是注册bean的别名
registerAlias|removeAlias|
getAliases|isAlias 只有这四个方法
6. ListableBeanFactory
可列举的beanFactory,通过条件获取beans,主要作用通过类型或注解或其他条件获取对应的bean
getBeansOfType|getBeanNamesForType|findAnnotationOnBean 等方法
7. AutoWireCapableBeanFactory
可自动装配的factory,在获取Bean的时候,如果bean还没有创建则会创建
默认实现AbstractAutowireCapableBeanFactory#createBean
ioc、aop等逻辑都嵌套在内
resolveDependency|resolveBeanByName| applyBeanPostProcessorsBeforeInitialization|applyBeanPostProcessorsBeforeInitialization等其他方法
- resolveDependency
在自动装配的时候会通过此方法获取可被装配的值
8. ConfigurableListableBeanFactory和ConfigurableBeanFactory
生产bean时、装配时、类型转化时、销毁bean、冻结等配置各种各样的组件供方便使用
registerResolvableDependency|ignoreDependencyInterface|
registerScope|addBeanPostProcessor|
freezeConfiguration|isConfigurationFrozen|
preInstantiateSingletons|destroySingletons|
setTypeConverter|setConversionService等其他方法
- registerResolvableDependency
注册一个bean,其他依赖此类型的,可以直接用,autowiredValue不会放到bean工厂中,只会为其他类提供依赖 - ignoreDependencyInterface
自动装配时忽略某个类型,通常配合beanFactory的addBeanPostProcessor一起使用。当bean初始化完后,BeanPostProcessor专门set忽略的字段
如常用的如ServletContextAwareProcessor、EnvironmentAware、ApplicationContextAware等 - registerScope
除单例和prototype之外有request、session等bean的生命周期定义都是由这个方法完成注册。通过Scope接口中的get方法获取bean
9. DefaultListableBeanFactory为以上全部接口的默认实现
beanFactory大体工作流程
1 获取beanFactory
context初始化时就自动创建好了
默认实现org.springframework.beans.factory.support.DefaultListableBeanFactory
this.beanFactory = new DefaultListableBeanFactory()
2. 准备beanFactory
beanFactory是刚new出来,没有经过配置,prepareBeanFactory方法对beanFactory进行一些简单的配置
如注册ApplicationContextAwareProcessor,调用registerResolvableDependency注册BeanFactory、ApplicationContext等
3. 交给context实现类去配置beanFactory
例如:如果是servletBeanApplicationContext会对beanFactory增加额外的Scope:registerScope,比如RequestScope、SessionScope等
4. 调用BeanFactoryPostProcessors
针对beanFactory注册一些的bean、移除一些bean,等其他操作
总之beanFactory不关心具体的实现,只调用后置处理器并把beanFactory作为参数传递过去即可
调用beanFactory的后置处理(beanFactory已经创建了)
BeanFactoryPostProcessor:针对ConfigurableListableBeanFactory初始化后的后置处理
BeanDefinitionRegistryPostProcessor:针对BeanDefinitionRegistry初始化后的后置处理
BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子类,会优先调用子类
- 那BeanFactoryPostProcessor具体的实现都有哪些、以及调用顺序是什么呢
- 具体的实现
- context有一个beanFactoryPostProcessors成员,在context初始化的时候可以往里面添加
默认有LazyInitializationBeanFactoryPostProcessor:如果条件满足,则设置全部的bean为懒加载、PropertySourceOrderingPostProcessor:把defaultProperties配置文件的优先级降到最低,等 - context持有beanFactory,在context初始化的时候会往beanFactory注册BeanDefinition
默认注册的有ConfigurationClassPostProcessor,会扫描所有、注册符合条件的bean等其他
具体可参考AnnotationConfigUtils#registerAnnotationConfigProcessors
- context有一个beanFactoryPostProcessors成员,在context初始化的时候可以往里面添加
- 调用的顺序
- context里面的beanFactoryPostProcessors成员,如果是
BeanDefinitionRegistryPostProcessor
类型,则优先调用,优先级是最高的 - 然后从beanFactory获取
BeanDefinitionRegistryPostProcessor
类型,优先调用实现了PriorityOrdered
的接口 - 然后从beanFactory获取
BeanDefinitionRegistryPostProcessor
类型,调用实现了Ordered
的接口 - 然后从beanFactory获取
BeanDefinitionRegistryPostProcessor
类型,经过排序之后、在调用没有调用过的。直到调用完beanFactory里面所有BeanDefinitionRegistryPostProcessor类型的bean为止 - 因为BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子类,所以等调用完所有1,2,3,4步骤对应的BeanDefinitionRegistryPostProcessor之后接着调用1、2、3、4步骤中的BeanFactoryPostProcessor
- 调用context里面的beanFactoryPostProcessors成员且只是
BeanFactoryPostProcessor
的类型 - 然后从beanFactory获取
BeanFactoryPostProcessor
类型的所有BeanName,优先调用实现了PriorityOrdered
的接口,在调用实现了Ordered
的接口,最后未调用过的经排序之后在调用
- context里面的beanFactoryPostProcessors成员,如果是
- 具体的实现
5. 注册拦截bean创建的bean处理器-BeanPostProcessor
它的作用就是在bean实例化前、后,初始化前、后进行拦截操作
- BeanPostProcessor注册顺序是什么呢?
- 从beanFactory获取
BeanPostProcessor
类型的所有beanNames - 遍历所有的beanNames,优先注册实现了
PriorityOrdered
的接口、然后在注册实现了Ordered
的接口,最后未注册过的经排序之后在注册 - 等所有的BeanPostProcessor注册完之后,如果是MergedBeanDefinitionPostProcessor类型的话注册顺序都会移到最后面哦
- 从beanFactory获取
6. 初始化国际化资源
7. 初始化事件广播器
不同于spring启动的listener,这个事件广播器用户是可以用来广播自定义事件并自定义监听的
默认广播器的实现SimpleApplicationEventMulticaster
使用时注入
ApplicationEventPublisher
bean,调用publishEvent方法,监听者需实现ApplicationListener
接口即可使用
8. onRefresh初始化webServer
如果是servletContext,则会在此阶段初始化内嵌的tomcat,并扫描所有的servlet、filter、其他servlet注册器等并关联到servletContext中
9. 获取并广播以注解形式存在的ApplicationListener
在spring启动流程中通过spring-spi方式获取bean来事件广播,如果某些bean非spi配置的方式,而是以注解形式配置的,则广播不了
所以在此阶段通过beanFactory获取以注解形式存在的listener,并把之前已广播的事件再次广播(伪事件,因为已经过了那个阶段了)
10. 实例化所有bean
实例化之前,优先实例化LoadTimeWeaverAware类型的bean(增强AOP,通过修改字节码实现AOP,class已加载过的话则不起作用,但是在这个阶段class基本上都已经被加载过)
实例化notLazyBean、singletonBean、如果为factoryBean,必须实现
SmartFactoryBean
接口且方法isEagerInit
返回true才可以实例化notLazy And singletons 的bean是从哪里来的呢?
都是通过BeanDefinitionRegistry注册的bean实例化完之后如果是单例的bean并且实现了
SmartInitializingSingleton
接口,则会按照bean的注册顺序依次调用afterSingletonsInstantiated
11 收尾工作-发布相对应的事件
- 获取所有Lifecycle类型的bean,如果是SmartLifecycle的类型并且isAutoStartup为true,则调用start方法
- 发布contextRefreshedEvent
- 把bean的信息注册到ManagementFactory(java监控工厂)
至此beanFactory流程解析完成后续继续分析bean实例化,ioc,aop