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);
...全文
847 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
wangbiao007 2019-10-28
  • 打赏
  • 举报
回复
牛逼,网上没有一个对sringboot刷新所做的工作有这么详细的讲解
三笠爷 2018-06-29
  • 打赏
  • 举报
回复
写错地了,想分享一篇Refresh的文章
stacksoverflow 2018-06-13
  • 打赏
  • 举报
回复
没看明白你想问啥?
视频详细讲解,需要的小伙伴自行百度网盘下载,链接见附件,永久有效。 1、课程简介 Spring框架是一系列应用框架的核心,也可以说是整合其他应用框架的基座。同时还是SpringBoot的基础。在当下的市场开发环境中,Spring占据的地位是非常高的,基本已经成为了开发者绕不过去的框架了。它里面包含了SpringSpringMVC,SpringData(事务),SrpingTest等等。 其中: Spring本身里面包含了两大核心IOC和AOP。IOC负责降低我们代码间的依赖关系,使我们的项目灵活度更高,可复用性更强。AOP是让方法间的各个部分更加独立,达到统一调用执行,使后期维护更加的方便。 SpringMVC本身是对Servlet和JSP的API进行了封装,同时在此基础上进一步加强。它推出的一套注解,可以降低开发人员的学习成本,从而更轻松的做表现层开发。同时,在3.x版本之后,它开始之初Rest风格的请求URL,为开发者提供了开发基于Restful访问规则的项目提供了帮助。 SpringData是一组技术合集。里面包含了JDBC,Data JPA,Data Redis,Data Mongodb,Data Rabbit,Data ElasticSearch等等。合集中的每一项都是针对不同数据存储做的简化封装,使我们在操作不同数据库时,以最简洁的代码完成需求功能。 SpringTest它是针对Junit单元测试的整合。让我们在开发中以及开发后期进行测试时,直接使用Junit结合spring一起测试。 本套课程中,我们将全面剖析SpringSpringMVC两个部分。从应用场景分析,到基本用法的入门案例,再到高级特性的分析及使用,最后是执行原理的源码分析。让学生通过学习本套课程不仅可以知其然,还可以知其所以然。最终通过一个综合案例,实现灵活运用Spring框架中的各个部分。 2、适应人群 学习spring,要有一定的Java基础,同时应用过spring基于xml的配置。(或者学习过官网的Spring课程) 学习springmvc,要有一定java web开发基础。同时对spring框架要有一定了解。 3、课程亮点 系统的学习Spring框架中各个部分,掌握Spring中一些高级特性的使用。 l Spring IoC n 设计模式-工厂模式 n 基础应用-入门案例 n 基础应用-常用注解使用场景介绍及入门 n 高级特性-自定义BeanNameGenerator n 高级特性-自定义TypeFilter n 高级特性-ImportSelector和ImportBeanDefinitionRegistrar的分析 n 高级特性-自定义ImportSelector n 高级特性-FilterType中的AspectJTypeFilter的使用 n 高级特性-自定义ImportBeanDefinitionRegistrar n 高级特性-自定义PropertySourceFactory实现解析yaml配置文件 n 源码分析-BeanFactory类视图和常用工厂说明 n 源码分析-AnnotationConfigApplicationContext的register方法 n 源码分析-AnnotationConfigApplicationContext的scan方法 n 源码分析-AbstractApplicationContext的refresh方法 n 源码分析-AbstractBeanFactory的doGetBean方法 l Spring Aop n 设计模式-代理模式 n 编程思想-AOP思想 n 基础应用-入门案例 n 基础应用-常用注解 n 高级应用-DeclareParents注解 n 高级应用-EnableLoadTimeWeaving n 源码分析-@EnableAspectJAutoproxy注解加载过程分析 n 源码分析-AnnotationAwareAspectJAutoProxyCreator n 技术详解-切入点表达式详解 l Spring JDBC n 基础应用-JdbcTemplate的使用 n 源码分析-自定义JdbcTemplate n 设计模式-RowMapper的策略模式 n 高级应用-NamedParameterJdbcTemplate的使用 n 源码分析-TransactionTemplate n 源码分析-DataSourceUtils n 源码分析-TransactionSynchronizationManager

50,599

社区成员

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

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