焦点快播:spring启动流程 (1) 流程概览
本文将通过阅读AnnotationConfigApplicationContext源码,分析Spring启动流程。
创建AnnotationConfigApplicationContext
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();applicationContext.register(XxConfig.class);applicationContext.register(YyConfig.class);applicationContext.refresh();XxService xxService = applicationContext.getBean(XxService.class);
核心的启动逻辑都在refresh方法中。
(资料图片)
构造方法
public AnnotationConfigApplicationContext() {this.reader = new AnnotatedBeanDefinitionReader(this);this.scanner = new ClassPathBeanDefinitionScanner(this);}
AnnotatedBeanDefinitionReader类
定义了多个register方法,用于向Spring容器注册BeanDefinition。
在创建AnnotatedBeanDefinitionReader时,会向容器注册几个注解驱动处理器:
- org.springframework.context.annotation.internalConfigurationAnnotationProcessor: ConfigurationClassPostProcessor
- BeanFactoryPostProcessor实现,用于解析@Configuration类。
- 按优先级排序,因为在@Configuration类中声明的任何@Bean方法都必须在任何其他BeanFactoryPostProcessor执行之前注册其对应的BeanDefinition。
- org.springframework.context.annotation.internalAutowiredAnnotationProcessor: AutowiredAnnotationBeanPostProcessor
- BeanPostProcessor实现类。
- @Autowired支持处理器。
- org.springframework.context.annotation.internalCommonAnnotationProcessor: CommonAnnotationBeanPostProcessor
- BeanPostProcessor实现类。
- 支持Resource、PostConstruct、PreDestroy等注解。
- org.springframework.context.event.internalEventListenerProcessor: EventListenerMethodProcessor
- org.springframework.context.event.internalEventListenerFactory: DefaultEventListenerFactory
ClassPathBeanDefinitionScanner类
BeanDefinition扫描器,在类路径上检测Bean,并将其注册到Spring容器中。扫描的类是通过类型过滤器检测到的。
refresh方法
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) {// 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();}}}
prepareRefresh方法
Prepare this context for refreshing, setting its startup date and active flag as well as performing any initialization of property sources.
protected void prepareRefresh() {// Switch to active.this.startupDate = System.currentTimeMillis();this.closed.set(false);this.active.set(true);// Initialize any placeholder property sources in the context environment.// Replace any stub property sources with actual instances.// web相关的ApplicationContext有实现initPropertySources();// Validate that all properties marked as required are resolvable:// see ConfigurablePropertyResolver#setRequiredPropertiesgetEnvironment().validateRequiredProperties();// Store pre-refresh ApplicationListeners...if (this.earlyApplicationListeners == null) {this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);} else {// Reset local application listeners to pre-refresh state.this.applicationListeners.clear();this.applicationListeners.addAll(this.earlyApplicationListeners);}// Allow for the collection of early ApplicationEvents,// to be published once the multicaster is available...this.earlyApplicationEvents = new LinkedHashSet<>();}
obtainFreshBeanFactory方法
Tell the subclass to refresh the internal bean factory.
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {refreshBeanFactory();return getBeanFactory();}
由于AnnotationConfigApplicationContext继承了GenericApplicationContext类,所以此处获取到的是DefaultListableBeanFactory对象。
prepareBeanFactory方法
配置BeanFactory的标准上下文,例如上下文的ClassLoader和后置处理器。
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// Tell the internal bean factory to use the context"s class loader etc.beanFactory.setBeanClassLoader(getClassLoader());// Standard implementation of the BeanExpressionResolver interface,// parsing and evaluating Spring EL using Spring"s expression module.beanFactory.setBeanExpressionResolver( new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));// Configure the bean factory with context callbacks.// 支持EnvironmentAware, MessageSourceAware, ApplicationContextAware等beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));beanFactory.ignoreDependencyInterface(EnvironmentAware.class);beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);beanFactory.ignoreDependencyInterface(MessageSourceAware.class);beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);// BeanFactory interface not registered as resolvable type in a plain factory.// MessageSource registered (and found for autowiring) as a bean.beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);beanFactory.registerResolvableDependency(ResourceLoader.class, this);beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);beanFactory.registerResolvableDependency(ApplicationContext.class, this);// ApplicationListenerDetector处理器自动将ApplicationListener类型Bean添加容器beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));// Detect a LoadTimeWeaver and prepare for weaving, if found.if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));// Set a temporary ClassLoader for type matching.beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}// 注册env beanif (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());}if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());}if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {beanFactory .registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());}}
postProcessBeanFactory方法
Modify the application context"s internal bean factory after its standard initialization. All bean definitions will have been loaded, but no beans will have been instantiated yet. This allows for registering special BeanPostProcessors etc in certain ApplicationContext implementations.
在标准初始化之后修改ApplicationContext的内部bean工厂。所有的BeanDefinition都将被加载,但还没有任何Bean被实例化。这允许在某些ApplicationContext实现中注册特殊的BeanPostProcessors等。
invokeBeanFactoryPostProcessors方法
实例化并调用注册的所有BeanFactoryPostProcessor,如果指定顺序则按照顺序调用,必须在单例实例化之前调用。
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {// 调用BeanFactoryPostProcessorsPostProcessorRegistrationDelegate .invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}}
调用BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor。
registerBeanPostProcessors方法
实例化并注册所有BeanPostProcessor,如果指定顺序则按照顺序注册,必须在应用Bean实例化之前调用。
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);}
把BeanPostProcessor实例添加到beanPostProcessors中:
- 从容器获取所有的BeanPostProcessor Bean
- 按照以下顺序注册:实现了PriorityOrdered接口、实现了Ordered接口、普通BeanPostProcessor、实现MergedBeanDefinitionPostProcessor接口
private static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, List postProcessors) {for (BeanPostProcessor postProcessor : postProcessors) {beanFactory.addBeanPostProcessor(postProcessor);}}
initMessageSource方法
国际化。
protected void initMessageSource() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);// Make MessageSource aware of parent MessageSource.if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;if (hms.getParentMessageSource() == null) {// Only set parent context as parent MessageSource if no parent MessageSource// registered already.hms.setParentMessageSource(getInternalParentMessageSource());}}} else {// Use empty MessageSource to be able to accept getMessage calls.DelegatingMessageSource dms = new DelegatingMessageSource();dms.setParentMessageSource(getInternalParentMessageSource());this.messageSource = dms;beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);}}
initApplicationEventMulticaster方法
初始化ApplicationEventMultimaster,如果Context中未定义,则使用SimpleApplicationEventMultimaster。
protected void initApplicationEventMulticaster() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {this.applicationEventMulticaster = beanFactory.getBean( APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);} else {this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);beanFactory.registerSingleton( APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);}}
onRefresh方法
可以重写的模板方法,以添加指定的刷新逻辑。在初始化特殊Bean时调用,在实例化单例之前调用。
默认什么都不做。
SpringBoot中的ServletWebServerApplicationContext实现类在这个阶段创建WebServer。
registerListeners方法
添加实现ApplicationListener的Bean作为侦听器。不会影响其他侦听器,这些侦听器可以在不使用Bean的情况下添加。
finishBeanFactoryInitialization方法
完成Bean工厂的初始化,初始化所有剩余的单例Bean。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {// Initialize conversion service for this context.if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {beanFactory.setConversionService(beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));}// Register a default embedded value resolver if no bean post-processor// (such as a PropertyPlaceholderConfigurer bean) registered any before:// at this point, primarily for resolution in annotation attribute values.if (!beanFactory.hasEmbeddedValueResolver()) {beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));}// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);for (String weaverAwareName : weaverAwareNames) {getBean(weaverAwareName);}// Stop using the temporary ClassLoader for type matching.beanFactory.setTempClassLoader(null);// Allow for caching all bean definition metadata, not expecting further changes.beanFactory.freezeConfiguration();// Instantiate all remaining (non-lazy-init) singletons.beanFactory.preInstantiateSingletons();}
finishRefresh方法
完成刷新工作,调用LifecycleProcessor的onRefresh()方法并发布ContextRefreshedEvent事件。
protected void finishRefresh() {// Clear context-level resource caches (such as ASM metadata from scanning).clearResourceCaches();// Initialize lifecycle processor for this context.initLifecycleProcessor();// Propagate refresh to lifecycle processor first.getLifecycleProcessor().onRefresh();// Publish the final event.publishEvent(new ContextRefreshedEvent(this));// Participate in LiveBeansView MBean, if active.LiveBeansView.registerApplicationContext(this);}
启动流程
- 创建AnnotationConfigApplicationContext对象
- 创建AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner
- 向容器注册几个注解驱动处理器:ConfigurationClassPostProcessor, AutowiredAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor等
- 调用applicationContext.register(XxConfig.class)注册配置类
- 调用refresh()方法:
- prepareRefresh方法准备工作:初始化PropertySources、validateRequiredProperties等
- Refresh the internal beanFactory
- 配置BeanFactory的标准上下文,例如上下文的ClassLoader和后置处理器
- 实例化并调用注册的所有BeanFactoryPostProcessor,如果指定顺序则按照顺序调用,必须在单例实例化之前调用
- 实例化并注册所有BeanPostProcessor,如果指定顺序则按照顺序注册,必须在应用Bean实例化之前调用
- 初始化MessageSource
- 初始化ApplicationEventMultimaster,如果Context中未定义,则使用SimpleApplicationEventMultimaster
- onRefresh方法,SpringBoot中的ServletWebServerApplicationContext实现类在这个阶段创建WebServer
- 添加实现ApplicationListener的Bean作为侦听器
- 完成Bean工厂的初始化,初始化所有剩余的单例Bean
- 完成刷新工作,调用LifecycleProcessor的onRefresh()方法并发布ContextRefreshedEvent事件
标签:
-
2022-05-23 16:13:32
上海奉贤等区开展常态化防疫压力测试 有序开放公交、公园、公共服务场所、公共街区商区<
本报上海5月21日电 (记者刘士安、曹玲娟)上海正在奉贤等区开展常态化防疫压力测试。在21日召开的上海市疫情防控工作新闻发布会上,奉
-
2022-05-23 16:13:32
“抗疫 宅家云课堂”,吸引沪上老同志观看50万人次<
由上海市委老干部局主办,上海市老干部大学、市科技助老服务中心承办的“抗疫 宅家云课堂”系列直播讲座自4月12日启动以来,深受老同
-
2022-05-23 16:13:32
“代跑腿”买药、开通绿色通道 丰台为管控区居民提供便捷医疗服务<
“真是太感谢了,解决了我的燃眉之急!”家住假日万恒社区的杨女士对前来送药的居委会工作人员说。 自5月17日6时起,丰台区对青塔街...
-
2022-05-23 16:13:32
上海嘉定:儿童计划免疫接种全部恢复,实行预约制<
在5月22日召开的上海市新冠肺炎疫情防控新闻发布会上,嘉定区副区长王浩介绍,从4月28日开始,嘉定在防范区逐步有序恢复老年人疫苗接种
-
2022-05-23 16:13:32
乡村振兴看新疆 | 种下红樱桃 结出“致富果”<
央广网阿图什5月22日消息(记者 罗成 通讯员 杨林)乡村振兴靠产业,产业发展靠特色。新疆阿图什市阿扎克镇麦依村积极引导农民因地制
-
2023-06-26 17:27:01
焦点快播:spring启动流程 (1) 流程概览
本文将通过阅读AnnotationConfigApplicationContext源码,分析Spring启
-
2023-06-26 16:51:52
各省高考状元已出,堪称神仙打架,一个比一个优秀,有人刷新纪录|环球观点
2023高考季 十二年寒窗苦读,披星戴月,这两天终于等到了各路学霸
-
2023-06-26 16:35:47
2023年东莞高考志愿填报系统入口-天天简讯
填报系统入口:https: pg eeagd edu cn ks2023年普通高校招生实行网上
-
2023-06-26 16:08:56
全球今日讯!meiwang(关于meiwang的基本详情介绍)
1、王思美。2、著名影视人员。3、曾经参与制作过《六月男孩》。本文关
-
2023-06-26 16:00:13
全球资讯:汉产“移动冷藏库”远销孟加拉
汉产“移动冷藏库”远销孟加拉---6月25日,武汉市科迈机械制造有限公司
-
2023-06-26 15:15:35
isk自带声卡_iSK首款自带声卡的麦克风iM8
hello大家好,我是城乡经济网小晟来为大家解答以上问题,isk自带声卡(
-
2023-06-26 14:52:11
滨州市科技馆赴济南图书场馆考察-当前时讯
通讯员苏宁宁为进一步深化“科普书吧”设计工作,打造具有滨州特色、满
-
2023-06-26 13:53:25
环球快播:古代宫女的下场_古代后宫的女人们为什么总是悲剧性收场
想必现在有很多小伙伴对于古代后宫的女人们为什么总是悲剧性收场方面的
-
2023-06-26 13:23:15
沈腾喊你打卡齐齐哈尔!福利门票等你拿!
齐齐齐哈尔是达斡尔语,意为“边疆”或“天然牧场”,因扎龙湿地栖息着
-
2023-06-26 12:50:57
超市分切水果引担忧:早晨切的西瓜,傍晚还新鲜吗?-天天播报
切成块的西瓜、预开口的椰子……炎热的夏天,超市、生鲜门店、菜市场的
-
2023-06-26 12:06:07
关于对娄底市开展省级生态环境保护督察的公告
关于对娄底市开展省级生态环境保护督察的公告经省委、省政府批准,湖南
-
2023-06-26 11:50:59
每日短讯:正态分布表常用_标准正态分布表怎么使用简介介绍
对于标准正态分布表怎么使用这个问题感兴趣的朋友应该很多,这个也是目
-
2023-06-26 11:13:12
999元6天5晚玩转大西北!天空之境、雪山花海、沙漠公路… 世界即时
今年书单狗的好多同事,都跑去了大西北!鄙狗都开始好奇了,那不是荒凉
-
2023-06-25 16:15:26
文化洋河|老洋河的坊
街坊这样千年积淀的历史和美酒,形成了洋河人独特的街坊文化。这正是:
-
2023-06-25 16:05:56
环球热文:后备厢空间有大幅提升 全新奔驰E级旅行版官图发布
日前,奔驰官方发布了一组全新奔驰E级旅行版的官图。新车基于全新一代
-
2023-06-25 14:57:22
当前关注:甘肃发布强对流黄色预警,注意防范雷暴大风冰雹
兰州中心气象台6月25日11时43分发布甘肃省强对流黄色预警:预计未来24
-
2023-06-25 14:45:26
光伏未来在海洋?苏鲁争相打造千万千瓦级基地 组件龙头实现供货_当前热门
从内陆、水库走向滩涂、海洋,中国光伏产业正在开启新一轮探索。日前,
-
2023-06-25 13:52:16
香港英文名字翻译_香港英文名字
1、香港的姓名译作英文是以粤语音为出发的,所以香港籍姓名的英文拼写
-
2023-06-25 13:14:12
2023 IAI国际设计节年度盛典在厦门举办
2023 IAI国际设计节暨第十四 十五届IAI全球设计奖颁奖盛典24日晚在
-
2023-06-25 12:52:20
世界讯息:生物安全柜与超净工作台原理的区别_生物安全柜与超净工作台的区别
1、最主要的是工作原理和应用方面不同生物安全柜是在玻璃操作橱中向内
-
2023-06-25 12:00:42
科伦 TROP-2 ADC 新适应证拟纳入突破性疗法|环球新动态
6月21日,据CDE官网显示,拟将科伦药业注射用SKB264纳入突破性疗法,用
-
2023-06-25 11:51:50
俄媒:普京签署法律规定“非重刑犯参军可提前释放”
据塔斯社6月24日报道,俄罗斯总统普京签署法律,其中规定罪犯在签订俄
-
2023-06-25 11:11:17
炎炎夏日遇见首尔 东航云南新开昆明首尔往返航线 每日热点
日前,东航云南公司新开昆明-首尔往返航线。
-
2023-06-25 10:45:12
我国将继续强化“三位一体”保护理念 严守耕地保护红线_新要闻
央视网消息:今天(6月25日)是第33个全国土地日,主题为“节约集约用
-
2023-06-25 10:02:09
视频生成模型 Zeroscope_v2_576w 开源
品玩6月25日讯,据huggingface页面显示,一款名为Zeroscope_v2_576w的
-
2023-06-25 10:05:20
广州接待市民游客近623万人次|世界热头条
较2019年增长4 5%新快报讯端午假期广州市共接待市民游客近623万人次,
-
2023-06-25 09:14:39
每日报道:贵州"村超"吸引力十足 榕江酒店端午订单暴涨11倍
多彩贵州网讯6月24日,携程发布2023端午假期旅行总结。贵州“村超”比
-
2023-06-25 08:54:09
精选!夜半三更盼天明寒冬腊月盼春风_这个歌叫什么名 歌词是 夜半三更哟 盼天明 寒冬腊月哟 盼春风 _
1、这句歌词是出自于歌曲《映山红》。2、歌名:映山红演唱:邓玉华词:
-
2023-06-25 07:45:21
当端午遇上烟雨江南 文明旅游成最美风景
徐凫岩景区,志愿者引导游客进入景区。 当端午遇上烟雨江南,会擦出
-
2023-06-25 06:53:44
天天观天下!黄龙玉原石值钱吗_我这块黄龙玉原石值多少钱呢
1、看外观只是一块黄蜡石,还达不到黄龙玉的标准,不过黄蜡石现在也挺
-
特写:风吹稻香忆袁老——袁隆平逝世一周年的墓前追思
2022-05-23 16:13:29 -
北京5月21日区域核酸筛查初筛10管混采阳性
2022-05-23 16:13:29 -
北京两地由高风险降为中风险 一地降为低风险地区
2022-05-23 16:13:29 -
5月21日15时至22日15时,北京新增本土新冠肺炎病毒感染者94例
2022-05-23 16:13:29 -
108岁病人顺利出院,瑞金医院卢湾分院已收治10位百岁老人
2022-05-23 16:13:29 -
生态花园助力乡村振兴 重庆小山村展现“乡土美学”
2022-05-23 16:13:29 -
上海金山政务服务场所逐步恢复服务
2022-05-23 16:13:29