spring源码refresh()刷新容器详解

三笠爷 2018-06-13 03:38:09

public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();

// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);

try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);

// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);

// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);

// Initialize message source for this context.
initMessageSource();

// Initialize event multicaster for this context.
initApplicationEventMulticaster();

// Initialize other special beans in specific context subclasses.
onRefresh();

// Check for listener beans and register them.
registerListeners();

// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);

// Last step: publish corresponding event.
finishRefresh();
}

catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + 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();
}
}
}

Spring容器refresh()创建刷新
1、prepareRefresh()刷新前的预处理
1)initPropertySources()初始化一些属性设置;子类自定义个性化的属性设置方法
2)getEnvironment().validateRequiredProperties();校验属性的合法等
3)earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>() 保存容器中一些早期的事件
2、obtainFreshBeanFactory();获取BeanFactory
1)refreshBeanFactory()刷新【创建】容器
创建了一个this.beanFactory = new DefaultListableBeanFactory();并设置序列化id
2)getBeanFactory();返回上一步创建的beanFactory对象
3)将创建BeanFactory【DefaultListableBeanFactory】返回
3、prepareBeanFactory(beanFactory);BeanFactory的预准备工作【beanFactory】的一些设置
1)设置beanFactory的类加载器、支持表达式解析器
2)添加部分ApplicationContextAwareProcessor
3)设置忽略的自动装配的接口EnvironmentAware、EmbeddedValueResolverAware等等
4)注册可以解析的自动装配;我们能直接在任何组件中自动注入
BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext
5)添加BeanPostProcessor【ApplicationListenerDetector】
6)添加编译时的AspectJ
7)给BeanFactory中注册一些能用的组件
environment【ConfigurableEnvironment】、systemProperties【Map<String, Object>】、systemEnvironment【Map<String, Object>】
4、postProcessBeanFactory(beanFactory)beanFactory准备工作完成后进行的后置处理工作
1)子类通过重写这个方法来在beanFactory创建并预准备完成以后做进一步的设置(在他子类实现)
----------------------------------------以上是beanFactory的创建以及预准备工作-----------------------
5、invokeBeanFactoryPostProcessors(beanFactory);
BeanFactoryPostProcessor:beanFactory的后置处理器。在beanFactory标准初始化之后执行的
两个接口:BeanDefinitionRegistryPostProcessor、BeanFactoryPostProcessor
先执行BeanDefinitionRegistryPostProcessor的方法
1)获取所有的BeanDefinitionRegistryPostProcessor
2)看先执行实现了PriorityOrdered接口的获取所有的BeanDefinitionRegistryPostProcessor
postProcessor.postProcessBeanDefinitionRegistry(registry)
3)在执行实现了Ordered顺序接口的BeanDefinitionRegistryPostProcessor
postProcessor.postProcessBeanDefinitionRegistry(registry)
4)最后执行没有任何优先级或者是顺序接口的BeanDefinitionRegistryPostProcessor
postProcessor.postProcessBeanFactory(beanFactory);
在执行BeanFactoryPostProcessor的方法
1)获取所有的BeanFactoryPostProcessor
2)看先执行实现了PriorityOrdered接口的获取所有的BeanFactoryPostProcessor
postProcessor.postProcessBeanFactory(beanFactory);
3)在执行实现了Ordered顺序接口的BeanFactoryPostProcessor
postProcessor.postProcessBeanFactory(beanFactory);
4)最后执行没有任何优先级或者是顺序接口的BeanFactoryPostProcessor
postProcessor.postProcessBeanFactory(beanFactory);
6、registerBeanPostProcessors(beanFactory);注册BeanPostProcessor(bean的后置处理器)【拦截创建】
不同接口类型的BeanPostProcessor;在Bean创建前后的执行时机是不一样的
InstantiationAwareBeanPostProcessor
DestructionAwareBeanPostProcessor
SmartInstantiationAwareBeanPostProcessor
MergedBeanDefinitionPostProcessor
1)获取所有的BeanPostProcessor;后置处理器都默认可以通过PriorityOrdered、Ordered接口执行优先级
2)先注册PriorityOrdered优先级的BeanPostProcessor;把没一个BeanPostProcessor添加到BeanFactory中
beanFactory.addBeanPostProcessor(postProcessor);
3)在注册Ordered接口的
beanFactory.addBeanPostProcessor(postProcessor);
4)最后注册没有任何优先级接口的
beanFactory.addBeanPostProcessor(postProcessor);
5)最终注册MergedBeanDefinitionPostProcessor接口的
beanFactory.addBeanPostProcessor(postProcessor);
6)注册一个ApplicationListenerDetector;来在bean创建完成后检查是否是ApplicationListener如果是监听器
applicationContext.addApplicationListener((ApplicationListener<?>) bean);
7、initMessageSource();初始化messageSource组件(做国际化功能)
1)获取BeanFactory
2)看容器中是否有id为messageSource的,类型是MessageSource的组件
如果有复制给messageSource,如果没有创建一个DelegatingMessageSource
MessageSource:取出国际化配置文件中的某个key的值;能按照区域信息获取
3)把创建好的MessageSource注册到容器中,以后获取国际化配置文件的值的时候可以自动注入MessageSource
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
8、initApplicationEventMulticaster()
1)获取BeanFactory
2)从BeanFactory中获取ApplicationEventMulticaster
3)如果没有上一步配置,那就创建一个SimpleApplicationEventMulticaster
4)将创建的ApplicationEventMulticaster添加到BeanFactory中,以后其他组件直接自动注入
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
9、onRefresh();留给子容器
1、子类重写这个方法,在容器刷新的时候可以自定义逻辑(比如增加组件)
10、registerListeners();
1)从容器中拿到所有的ApplicationListener
2)将每个监听器添加到时间派发器中
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
3)派发之前步骤产生的事件
11、finishBeanFactoryInitialization(beanFactory);初始化所有剩下的单实例bean
1、beanFactory.preInstantiateSingletons();初始化所有剩下的单实例bean
1)获取容器中的所有bean,依次进行初始化和创建对象
2)获取Bean的定义信息RootBeanDefinition
3)Bean不是抽象 是单例 不是懒加载
1)判断是否是FactoryBean;是否是实现FactoryBena接口的Bena
2)不是工厂Bean。利用getBean(beanName)创建对象
1.doGetBean(name, null, null, false)
2.先获取缓存中保存的单实例Bean。如果能获取到说明这个Bean之前被创建过(所有创建过的单实例Bean都会被缓存起来)
3.private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);
4. 缓存获取不到,开始Bean的创建对象流程
5.比较单钱Bean已经创建
6.获取Bean定义信息
7.获取当前Bean依赖的其他Bean;如果该有按照getBean()把依赖的Bean先创建出来mbd.getDependsOn();
1.createBean(beanName, mbd, args)
2.resolveBeforeInstantiation(beanName, mbdToUse)
【InstantiationAwareBeanPostProcessor】提前执行先触发
先触发 postProcessBeforeInstantiation()
如果有返回值 postProcessAfterInitialization()
3.如果【InstantiationAwareBeanPostProcessor】没有返回代理对象,调用4步
4.Object beanInstance = doCreateBean(beanName, mbdToUse, args);创建Bean
1、【创建Bean实例】createBeanInstance(beanName, mbd, args);
利用工厂方法或者对象的构造器创建出Bean实例
2、applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
调用后置处理器
3、【Bean属性赋值】populateBean(beanName, mbd, instanceWrapper)
赋值之前:
1.拿到InstantiationAwareBeanPostProcessor后置处理器
postProcessAfterInstantiation()
2.拿到InstantiationAwareBeanPostProcessor后置处理器
postProcessPropertyValues()
3.应用Bean属性的值,为属性利用setter方法等进行赋值
applyPropertyValues(beanName,mbd,bw,pvs)
4、【Bean初始化】InitializingBean(beanName,exposedObject,mbd)
1.【执行Aware方法】invokeAwareMethods(beanName, bean);执行以下xxxAware接口
BeanNameAware\BeanClassLoaderAware\BeanFactoryAware
2.【执行后置处理器初始化方法】applyBeanPostProcessorsBeforeInitialization
BeanPostProcessor.postProcessBeforeInitialization()
3.【执行初始化方法】invokeInitMethods(beanName, wrappedBean, mbd);
--是否是InitializingBean接口的实行;执行接口规定的初始化
--是不是自定义初始化方法
4.【执行后置处理器初始化之后】applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)
beanProcessor.postProcessAfterInitialization(result, beanName)
5.注册Bean的销毁方法并不是执行registerDisposableBeanIfNecessary(beanName, bean, mbd);
5) 将创建的bean添加到缓存中singletonObjects
ioc容器就是这些Map,很多的Map里面保存了单实例Bean,环境信息等
所有Bean都利用getBean创建完成以后检查所有Bean是否是SmartInitializingSingleton接口的如果是就执行smartSingleton.afterSingletonsInstantiated();
12、finishRefresh()完成BeanFactory的初始化创建工作,IOC容器就创建完成
1.initLifecycleProcessor()初始化和生命周期有关的后置处理器;LifecycleProcessor
默认从容器中找是否有LifecycleProcessor的组件
写一个LifecycleProcessor的实现类,可以在BeanFactory
void onRefresh();刷新完成
void onClose();关闭
2.getLifecycleProcessor().onRefresh();
拿到前面定义的生命周期处理器(BeanFactory) 回调onRefresh
3.publishEvent(new ContextRefreshedEvent(this));发布容器刷新完成事件
4.LiveBeansView.registerApplicationContext(this);
...全文
832 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
wangbiao007 2019-10-28
  • 打赏
  • 举报
回复
牛逼,网上没有一个对sringboot刷新所做的工作有这么详细的讲解
三笠爷 2018-06-29
  • 打赏
  • 举报
回复
写错地了,想分享一篇Refresh的文章
stacksoverflow 2018-06-13
  • 打赏
  • 举报
回复
没看明白你想问啥?

50,530

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧