SpringBoot是如何动起来的
程序入口
SpringApplication.run(BeautyApplication.class, args);
执行此方法来加载整个SpringBoot的环境。
1.从哪儿开始?
SpringApplication.java
/*** Run the Spring application, creating and refreshing a new* {@link ApplicationContext}.* @param args the application arguments (usually passed from a Java main method)* @return a running {@link ApplicationContext}*/public ConfigurableApplicationContext run(String... args) {//...}
调用SpringApplication.java中的run方法,目的是加载Spring Application,同时返回ApplicationContext。
2.执行了什么?
2.1计时
记录整个Spring Application的加载时间!
StopWatch stopWatch = new StopWatch();
stopWatch.start();
// ...
stopWatch.stop();
if (this.logStartupInfo) {new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}
2.2声明
// 声明 ApplicationContext
ConfigurableApplicationContext context = null;
// 声明 一个异常报告集合
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
2.3指定程序运行模式
指定java.awt.headless,默认是true
一般是在程序开始激活headless模式,告诉程序,现在你要工作在Headless mode下,就不要指望硬件帮忙了,你得自力更生,依靠系统的计算能力模拟出这些特性来。
private void configureHeadlessProperty() {System.setProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, System.getProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, Boolean.toString(this.headless)));
}
2.4配置监听并发布应用启动事件
SpringApplicationRunListener负责加载ApplicationListener事件。
SpringApplicationRunListeners listeners = getRunListeners(args);
// 开始
listeners.starting();
// 处理所有 property sources 配置和 profiles 配置,准备环境,分为标准 Servlet 环境和标准环境
ConfigurableEnvironment environment = prepareEnvironment(listeners,applicationArguments);
// 准备应用上下文
prepareContext(context, environment, listeners, applicationArguments,printedBanner);
// 完成
listeners.started(context);
// 异常
handleRunFailure(context, ex, exceptionReporters, listeners);
// 执行
listeners.running(context);
getRunListeners中根据type = SpringApplicationRunListener.class去拿到了所有的Listener并根据优先级排序。
对应的就是META-INF / spring.factories文件中的org.springframework.boot.SpringApplicationRunListener = org.springframework.boot.context.event.EventPublishingRunListener
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type,Class<?>[] parameterTypes, Object... args) {ClassLoader classLoader = Thread.currentThread().getContextClassLoader();// Use names and ensure unique to protect against duplicatesSet<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));List<T> instances = createSpringFactoriesInstances(type, parameterTypes,classLoader, args, names);AnnotationAwareOrderComparator.sort(instances);return instances;}
在ApplicationListener中,可以针对任何一个阶段插入处理代码。
public interface SpringApplicationRunListener {/*** Called immediately when the run method has first started. Can be used for very* early initialization.*/void starting();/*** Called once the environment has been prepared, but before the* {@link ApplicationContext} has been created.* @param environment the environment*/void environmentPrepared(ConfigurableEnvironment environment);/*** Called once the {@link ApplicationContext} has been created and prepared, but* before sources have been loaded.* @param context the application context*/void contextPrepared(ConfigurableApplicationContext context);/*** Called once the application context has been loaded but before it has been* refreshed.* @param context the application context*/void contextLoaded(ConfigurableApplicationContext context);/*** The context has been refreshed and the application has started but* {@link CommandLineRunner CommandLineRunners} and {@link ApplicationRunner* ApplicationRunners} have not been called.* @param context the application context.* @since 2.0.0*/void started(ConfigurableApplicationContext context);/*** Called immediately before the run method finishes, when the application context has* been refreshed and all {@link CommandLineRunner CommandLineRunners} and* {@link ApplicationRunner ApplicationRunners} have been called.* @param context the application context.* @since 2.0.0*/void running(ConfigurableApplicationContext context);/*** Called when a failure occurs when running the application.* @param context the application context or {@code null} if a failure occurred before* the context was created* @param exception the failure* @since 2.0.0*/void failed(ConfigurableApplicationContext context, Throwable exception);}
3.每个阶段执行的内容
3.1 listeners.starting();
在加载Spring Application之前执行,所有资源和环境未被加载。
3.2 prepareEnvironment(listeners,applicationArguments);
创建ConfigurableEnvironment;
将配置的环境绑定到Spring Application中;
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,ApplicationArguments applicationArguments) {// Create and configure the environmentConfigurableEnvironment environment = getOrCreateEnvironment();configureEnvironment(environment, applicationArguments.getSourceArgs());listeners.environmentPrepared(environment);bindToSpringApplication(environment);if (this.webApplicationType == WebApplicationType.NONE) {environment = new EnvironmentConverter(getClassLoader()).convertToStandardEnvironmentIfNecessary(environment);}ConfigurationPropertySources.attach(environment);return environment;}
3.3 prepareContext
配置忽略的豆;
private void configureIgnoreBeanInfo(ConfigurableEnvironment environment) {if (System.getProperty(CachedIntrospectionResults.IGNORE_BEANINFO_PROPERTY_NAME) == null) {Boolean ignore = environment.getProperty("spring.beaninfo.ignore",Boolean.class, Boolean.TRUE);System.setProperty(CachedIntrospectionResults.IGNORE_BEANINFO_PROPERTY_NAME,ignore.toString());}}
打印日志 - 加载的资源
Banner printedBanner = printBanner(environment);
根据不同的WebApplicationType创建上下文
context = createApplicationContext();
3.4 refreshContext
支持定制刷新
/*** Register a shutdown hook with the JVM runtime, closing this context* on JVM shutdown unless it has already been closed at that time.* <p>This method can be called multiple times. Only one shutdown hook* (at max) will be registered for each context instance.* @see java.lang.Runtime#addShutdownHook* @see #close()*/void registerShutdownHook();
3.5 afterRefresh
刷新后的实现方法暂未实现
/*** Called after the context has been refreshed.* @param context the application context* @param args the application arguments*/protected void afterRefresh(ConfigurableApplicationContext context,ApplicationArguments args) {}
3.6 listeners.started(context);
到此为止,Spring Application的环境和资源都加载完毕了;
发布应用上下文启动完成事件;
执行所有Runner运行器 - 执行所有ApplicationRunner和CommandLineRunner这两种运行器
// 启动
callRunners(context, applicationArguments);
3.7 listeners.running(context);
触发所有SpringApplicationRunListener监听器的running事件方法
SpringBoot是如何动起来的相关推荐
- 厉害了!SpringBoot是如何动起来的!
作者:襄垣 juejin.im/post/5c6f730ce51d457f14363a53 程序入口 SpringApplication.run(BeautyApplication.class, ar ...
- java基于Springboot+Vue的动漫漫画周边商品销售商城 elementui
系统管理也都将通过计算机进行整体智能化操作,对于动漫周边商城所牵扯的管理及数据保存都是非常多的,例如管理员:首页.个人中心.用户管理.卖家管理.商品分类管理.商品信息管理.订单通知管理.发货物资管理. ...
- 基于SpringBoot+Vue的动漫漫画投稿网站 element
随着互联网的发展和网民年龄的年轻化,更多的人喜欢通过看漫画来度过自己的闲暇时间,但是当前漫画市场良莠不齐,且很多漫画网站都是收费的,为了给用户提供一个免费且全面的漫画场所我们开发了本次的漫画之家系统, ...
- 基于SpringBoot框架的动漫模型仓储管理系统
社会的发展和科学技术的进步,互联网技术越来越受欢迎.网络计算机的生活方式逐渐受到广大人民群众的喜爱,也逐渐进入了每个用户的使用.互联网具有便利性,速度快,效率高,成本低等优点. 因此,构建符合自己要求 ...
- 基于JAVA动漫网站和特效处理系统(Springboot框架+AI人工智能) 开题报告
本科生毕业论文 基于Java(springboot框架)动漫网站和特效处理系统 开题报告 学 院: 专 业: 计算机科学与技术 年 级: 学生姓名: 指导教师: XXXX大学 ...
- 玩转springboot:入门程序
Spring Boot 入门 一.Spring Boot 简介 官网英文: Spring Boot makes it easy to create stand-alone, production-gr ...
- Java微服务篇1——SpringBoot
Java微服务篇1--SpringBoot 1.什么是springboot 1.1.Spring出现的问题 Spring是Java企业版(Java Enterprise Edition,JEE,也称J ...
- 通俗易懂的SpringBoot教程---day1---Springboot入门教程介绍
通俗易懂的SpringBoot教程-day1-教程介绍 教程介绍: 初级教程: 一. Spring Boot入门 二. Spring Boot配置 三. Spring Boot与日志 四. Sprin ...
- springboot Hello World探究
Hello World探究 1.POM文件 1.父项目 <parent><groupId>org.springframework.boot</groupId>< ...
最新文章
- python中文件读写位置的作用-文件操作,读,写,指定位置
- python编程小组信息程序下载_300种 Python 编程图书大集合(FTP服务器下载) (豆瓣 Python编程小组)...
- 详解虚函数的实现过程之菱形继承修罗场(6)
- c调用python打包_如何将C++的API封装成python可调用形式?
- Python_列表常用操作
- Linux信号实现精确到微秒的sleep函数:通过sigsuspend函数解决时序竞态问题
- 关于多数据源(除自己数据库外,另一部分数据需通过接口调取第三方获取)的查询问题...
- Hadoop学习之web查看HADOOP以及文件的上传和下载
- foremost windows_windows上安装foremost - kalibb
- 算法精解----快速排序(方式1)
- VPS部署以及域名设置和DNS解析
- vscode 折叠所有区域代码快捷键
- C++ QT开发人机象棋(棋子走法)
- 基于腾讯地图定位组件实现周边POI远近排序分布图
- Work from home
- 重庆华侨城跨界联合潮牌T.M.D PCP发财潮流文化艺术聚会国庆开档
- 在多个 PDF 中查找文本
- 基于Spark的巨型矩阵分布式LU计算求逆【第一篇】
- 自适应流媒体传输(四)——深入理解MPD
- flutter中的可选参数
热门文章
- 使用Jna调用dll函数库(java使用jna对接硬件接口)
- 软件架构设计 大型网站技术架构与业务架构融合之道
- 【HEVC代码阅读】帧内预测
- 嵌入式Linux能调用cheese吗,嵌入式系统BootLoader技术内幕
- 你知道什么是 a站、b站、c站、d站、e站、f站、g站、h站、i站、j站、k站、l站、m站、n站…z 站吗 ?...
- 什么是AOP,AOP能干什么,有什么优点
- 计算机和音乐结合的作品,用计算机创作多媒体作品──音乐和声音张燕.doc
- 2017年技术教练认证流程回顾
- 计算机毕业设计之Android的游戏账号交易平台APP(源码+系统+mysql数据库+Lw文档)
- 你必须知道的最好的开源WEB 资源