Spring容器的refresh方法
BeanFactory的创建以及准备
- prepareRefresh 刷新前的预处理
- initPropertySources() 初始化一些设置; 子类自定义个性化的属性设置方法;
getEnvironment().validateRequiredProperties();
校验属性的合法等this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
保存容器中一些早期的事件;
obtainFreshBeanFactory();
获取BeanFactoryrefreshBeanFactory();
- 创建了一个
this.beanFactory = new DefaultListableBeanFactory();
- 设置id
- 创建了一个
getBeanFactory()
返回上一步的beanFactory- 将创建的BeanFactory返回
prepareBeanFactory(beanFactory);
BeanFactory的准备工作(BeanFactory进行一些设置)- 设置BeanFactory的类加载器, 支持表达式解析器
- 添加部分BeanPostProcessor [ApplicationContextAwareProcessor]
- 设置忽略的自动装配的接口 [EnvironmentAware,EmbeddedValueResolverAware…]
- 注册可以解析的自动装配 ,我们可以在任何组件中自动注入[BeanFactory,ResourceLoader,ApplicationEventPublisher,ApplicationContext]
- 添加BeanPostProcessor
- 添加编译时的AspectJ支持
- 给BeanFactory中注册一些能用的组件:
-
environment
systemProperties
systemEnvironment
-
postProcessBeanFactory(beanFactory);
BeanFactory准备工作完成后进行的后置处理工作- 子类通过重写这个方法在BeanFactory创建并准备完成后进一步的设置
BeanFactoryPostProcessor
接着往下说
invokeBeanFactoryPostProcessors(beanFactory);
执行BeanFactoryPostProcessors;- BeanFactoryPostProcessors: BeanFactory的后置处理器, 在BeanFactory标准初始化之后进行的
- 两个相关接口:
BeanFactoryPostProcessor
和BeanDefinitionRegistryPostProcessor
- 执行
BeanFactoryPostProcessor
的方法- 先执行
BeanDefinitionRegistryPostProcessor
- 获取所有的
BeanDefinitionRegistryPostProcessor
- 按照优先级排序:
PriorityOrdered
->Ordered
指定顺序的 -> 没有实行任何优先级或者顺序接口的
- 获取所有的
- 再执行
BeanFactoryPostProcessor
- 先执行
- 两个相关接口:
- BeanFactoryPostProcessors: BeanFactory的后置处理器, 在BeanFactory标准初始化之后进行的
registerBeanPostProcessors(beanFactory);` 注册bean的后置处理器
不同接口类型的BeanPostProcessor, 在Bean创建前后执行时机是不一样的
DestructionAwareBeanPostProcessor
InstantiationAwareBeanPostProcessor
SmartInstantiationAwareBeanPostProcessor
MergedBeanDefinitionPostProcessor
获取所有的BeanPostProcessor
beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
后置处理器都默认可以通过PriorityOrdered,Ordered接口来指定优先级
先注册PritorityOrdered优先级接口的BeanPostProcessor
beanFactory.addBeanPostProcessor(postProcessor)
再注册Ordered接口的
最后注册没有实现优先级接口的
最终注册MergedBeanDefinitionPostProcessor
这测一个ApplicationListenerDetector: 在Bean创建完成后检查是否是ApplicationListener, 如果是,
this.applicationContext.addApplicationListener
国际化
- initMessageSource() 初始化MessageSource组件(做国际化,消息绑定,消息解析)
- 获取BeanFactory
- 看容器中是否有id为messageSource的, 类型是MessageSource的组件
- 如果有赋值给MessageSource, 如果没有, 自己创建一个DelegatingMessageSource
- 把创建好的MessageSource注册在容器中; 以后获取国际化配置文件值的时候,可以自动注入MessageSource
时间派发器
initApplicationEventMulticaster
初始化事件派发器- 获取BeanFactory
- 从BeanFactory中获取 applicationEventMulticaster (可以自行配置)
- 如果没有配置, 创建一个SimpleApplicationEventMulticaster
- 将创建的 applicationEventMulticaster 注入到容器 registerSingleton
onRefresh
留给子类- 子类可以重写这个方法, 在容器刷新时自定义逻辑
registerListeners
给容器中将所有项目里面的ApplicationListener
注册进来- 从容器中拿到所有的
ApplicationListener
- 将每个监听器添加到事件派发器中
- 派发之前步骤产生的事件
- 从容器中拿到所有的
初始化Bean
finishBeanFactoryInitialization(beanFactory);
初始化所有剩下的单实例beanbeanFactory.preInstantiateSingletons();
初始化获取容器中的所有Bean, 依次创建和初始化对象
获取Bean的定义信息
RootBeanDefinition
Bean不是抽象的, 是单实例的, 不是LazyInit的. 进行创建
判断是否是FactoryBean, 也就是是否实现了此接口->使用工厂方法创建
不是工厂Bean, 使用
getBean(beanName)
创建 (这里的方法跟直接调用ioc.getBean一样)getBean(beanName)
doGetBean(name, null, null, false);
先获取缓存中保存的单实例Bean, 如果能获取到, 说明这个Bean之前被创建过(所有创建过的Bean都会被缓存起来)
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
是从这里获取缓存中获取不到, 开始Bean的创建流程
标记当前bean被创建
markBeanAsCreated
获取Bean的定义信息
getMergedLocalBeanDefinition
获取当前Bean依赖的其他Bean
getDependsOn
;(这个也是配置在Beandepends-on
属性上的) 如果有, 按照getBean()
把依赖的Bean先创建出来启动单实例Bean的创建流程
createBean(beanName, mbd, args)
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
让BeanPostProcessor先拦截返回代理对象- 先触发
applyBeanPostProcessorsBeforeInstantiation
- 如果有返回值
applyBeanPostProcessorsAfterInitialization
- 先触发
如果前面的
resolveBeforeInstantiation
没有返回代理对象, 向下执行, 如果返回了代理对象, 结束创建.调用
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
创建Bean实例
obtainFromSupplier
利用SupplierinstantiateUsingFactoryMethod
利用工厂方法或构造器
applyMergedBeanDefinitionPostProcessors
调用MergedBeanDefinitionPostProcessor为属性赋值
populateBean
拿到
InstantiationAwareBeanPostProcessor
后置处理器; 执行postProcessAfterInstantiation
方法拿到
InstantiationAwareBeanPostProcessor
; 执行postProcessProperties
赋值 应用Bean属性的值; 为属性利用setter方法进行赋值:
applyPropertyValues(beanName, mbd, bw, pvs);
初始化
initializeBean
- 执行Aware接口的方法
invokeAwareMethods
[如BeanNameAware\BeanClassLoaderAware\BeanFactoryAware] - 执行后置处理器初始化之前的方法
applyBeanPostProcessorsBeforeInitialization
- 执行初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
- 是否是
InitializingBean
接口实现, 执行接口规定的初始化 - 是否是自定义初始化方法, 有则执行
invokeCustomInitMethod
- 是否是
- 执行后置处理器初始化之后的方法
applyBeanPostProcessorsAfterInitialization
- 执行Aware接口的方法
注册销毁方法
将创建的Bean添加到缓存中
singletonObjects
说白了IOC容器就是这种各样的Map; 很多的Map保存了单实例Bean, 各种环境信息;
所有的Bean都利用
getBean
创建完成后, 检查所有的Bean是否是SmartInitializingSingleton接口的; 如果是, 就执行afterSingletonsInstantiated
finishRefresh()
完成BeanFactory的初始化创建工作 -> IOC容器创建完成initLifycycleProcessor()
获取生命周期有关的后置处理器LifecycleProcessor
加入到容器中
默认从容器中找, 如果没有 new 一个DefaultLifecycleProcessor
可以写一个
拿到处理器, 调用onRefresh方法
发布容器刷新完成时间
publishEvent
至此, 粗略的刷新过程就是这样
总结
- Spring容器启动时会保存所有注册进来的Bean的定义信息
- xml
- annotation: @Service @Component @Bean
- Spring容器会在合适的实际创建Bean
- 用到这个bean的时候使用
getBean
方法创建, 创建好后保存在容器中 - 统一创建所有bean的时候``finishBeanFactoryInitialization`
- 用到这个bean的时候使用
- 后置处理器
- 每一个bean创建, 都会使用各种后置处理器进行处理, 来增强bean的功能
AnnotationAwareAspectJAutoProxyCreator
AOPAutowiredAnnotationBeanPostProcessor
处理自动注入
- 每一个bean创建, 都会使用各种后置处理器进行处理, 来增强bean的功能
- 事件驱动器
- ApplicationListener 监听
- ApplicationEventMulticaster 事件派发器