白茶清欢无别事,我在等风也等你。苦酒折柳今相离,无风无月也无你

调用SpringApplication.run

org.springframework.boot.SpringApplication#run(java.lang.Class<?>, java.lang.String...)
org.springframework.boot.SpringApplication#run(java.lang.Class<?>[], java.lang.String[])new SpringApplication(primarySources).run(args)
// 创建sprignApplication
org.springframework.boot.SpringApplication#SpringApplicationpublic SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {this.resourceLoader = resourceLoader;Assert.notNull(primarySources, "PrimarySources must not be null");// 保存传入的主配置类this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));// 根据运行环境决定webApplicationTypethis.webApplicationType = deduceWebApplicationType();// 去meta-inf/spring.factories文件找ApplicationContextInitializer并保存下来setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));// 去meta-inf/spring.factories文件找ApplicationListener并保存下来setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));// 决定主配置类this.mainApplicationClass = deduceMainApplicationClass();
}
// 根据运行环境决定webApplicationType
private WebApplicationType deduceWebApplicationType() {// 响应式应用if (ClassUtils.isPresent(REACTIVE_WEB_ENVIRONMENT_CLASS, null)&& !ClassUtils.isPresent(MVC_WEB_ENVIRONMENT_CLASS, null)) {return WebApplicationType.REACTIVE;}// 普通工程for (String className : WEB_ENVIRONMENT_CLASSES) {if (!ClassUtils.isPresent(className, null)) {return WebApplicationType.NONE;}}// web工程(这里会返回这个)return WebApplicationType.SERVLET;
}
// SpringApplication对象创建成功后调用run方法
org.springframework.boot.SpringApplication#run(java.lang.String...)public ConfigurableApplicationContext run(String... args) {StopWatchstopWatch = new StopWatch();stopWatch.start();ConfigurableApplicationContext context = null;Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();configureHeadlessProperty();// 去meta-inf/spring.factories文件找SpringApplicationRunListener并保存下来SpringApplicationRunListeners listeners = getRunListeners(args);// 循环调用listener的starting方法listeners.starting();try {// 把main函数参数封装起来ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);// 准备环境ConfigurableEnvironment environment = prepareEnvironment(listeners,applicationArguments);configureIgnoreBeanInfo(environment);// 打印springboot bannerBanner printedBanner = printBanner(environment);// 根据当前运行环境创建容器context = createApplicationContext();// 去meta-inf/spring.factories文件找SpringBootExceptionReporterexceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,new Class[] { ConfigurableApplicationContext.class }, context);// 容器预准备prepareContext(context, environment, listeners, applicationArguments,printedBanner);// 刷新容器,springioc容器在这里初始化加载的refreshContext(context);afterRefresh(context, applicationArguments);stopWatch.stop();if (this.logStartupInfo) {new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);}listeners.started(context);callRunners(context, applicationArguments);}catch (Throwable ex) {handleRunFailure(context, ex, exceptionReporters, listeners);throw new IllegalStateException(ex);}try {listeners.running(context);}catch (Throwable ex) {handleRunFailure(context, ex, exceptionReporters, null);throw new IllegalStateException(ex);}return context;
}org.springframework.boot.SpringApplication#prepareEnvironmentprivate ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,ApplicationArguments applicationArguments) {// 创建或获取一个环境ConfigurableEnvironment environment = getOrCreateEnvironment();// 配置环境configureEnvironment(environment, applicationArguments.getSourceArgs());// 循环调用environmentPrepared环境预准备方法listeners.environmentPrepared(environment);// 把环境绑定到springApplication对象上bindToSpringApplication(environment);if (this.webApplicationType == WebApplicationType.NONE) {environment = new EnvironmentConverter(getClassLoader()).convertToStandardEnvironmentIfNecessary(environment);}ConfigurationPropertySources.attach(environment);return environment;
}private void prepareContext(ConfigurableApplicationContext context,ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,ApplicationArguments applicationArguments, Banner printedBanner) {// 环境设置到容器中context.setEnvironment(environment);postProcessApplicationContext(context);// 调用容器初始化applyInitializers(context);// 循环listener调用contextPrepared容器预处理listeners.contextPrepared(context);if (this.logStartupInfo) {logStartupInfo(context.getParent() == null);logStartupProfileInfo(context);}// Add boot specific singleton beans(添加springboot独有的单实例bean)context.getBeanFactory().registerSingleton("springApplicationArguments",applicationArguments);if (printedBanner != null) {context.getBeanFactory().registerSingleton("springBootBanner", printedBanner);}// Load the sourcesSet<Object> sources = getAllSources();Assert.notEmpty(sources, "Sources must not be empty");load(context, sources.toArray(new Object[0]));// 循环调用listener的contextLoaded发布事件listeners.contextLoaded(context);
}org.springframework.boot.SpringApplication#refreshContext
org.springframework.boot.SpringApplication#refresh
// 到这里就很明显是之前讲ioc时讲到的方法
org.springframework.context.support.AbstractApplicationContext#refresh
// 调用onfresh,之前说过这个方法spring没做任何事情,但是springboot中有用到
org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext#onRefresh
// 创建web容器
org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext#createWebServerprivate void createWebServer() {WebServer webServer = this.webServer;ServletContext servletContext = getServletContext();if (webServer == null && servletContext == null) {// 获取web容器工厂,即获取tomcatServletWebServerFactoryServletWebServerFactory factory = getWebServerFactory();// 使用web容器工厂创建容器this.webServer = factory.getWebServer(getSelfInitializer());}else if (servletContext != null) {try {getSelfInitializer().onStartup(servletContext);}catch (ServletException ex) {throw new ApplicationContextException("Cannot initialize servlet context",ex);}}initPropertySources();
}org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory#getWebServerpublic WebServer getWebServer(ServletContextInitializer... initializers) {// 创建一个tomcatTomcat tomcat = new Tomcat();/** 设置tomcat的各项属性*/File baseDir = (this.baseDirectory != null ? this.baseDirectory: createTempDir("tomcat"));tomcat.setBaseDir(baseDir.getAbsolutePath());Connector connector = new Connector(this.protocol);tomcat.getService().addConnector(connector);customizeConnector(connector);tomcat.setConnector(connector);tomcat.getHost().setAutoDeploy(false);configureEngine(tomcat.getEngine());for (Connector additionalConnector : this.additionalTomcatConnectors) {tomcat.getService().addConnector(additionalConnector);}prepareContext(tomcat.getHost(), initializers);return getTomcatWebServer(tomcat);
}org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory#getTomcatWebServer
org.springframework.boot.web.embedded.tomcat.TomcatWebServer#TomcatWebServer(org.apache.catalina.startup.Tomcat, boolean)
org.springframework.boot.web.embedded.tomcat.TomcatWebServer#initializeprivate void initialize() throws WebServerException {TomcatWebServer.logger.info("Tomcat initialized with port(s): " + getPortsDescription(false));synchronized (this.monitor) {try {addInstanceIdToEngineName();Context context = findContext();context.addLifecycleListener((event) -> {if (context.equals(event.getSource())&& Lifecycle.START_EVENT.equals(event.getType())) {// Remove service connectors so that protocol binding doesn't// happen when the service is started.removeServiceConnectors();}});// 启动tomcatthis.tomcat.start();// We can re-throw failure exception directly in the main threadrethrowDeferredStartupExceptions();try {ContextBindings.bindClassLoader(context, context.getNamingToken(),getClass().getClassLoader());}catch (NamingException ex) {// Naming is not enabled. Continue}// 启动阻塞的非守护线程来阻塞tomcatstartDaemonAwaitThread();}catch (Exception ex) {stopSilently();throw new WebServerException("Unable to start embedded Tomcat", ex);}}
}

springboot内嵌tomcat的jar包启动流程相关推荐

  1. 指定SpringBoot内嵌Tomcat的版本,修复(CVE-2021-42340)漏洞

    1.Tomcat漏洞 近日,Apache Tomcat 发布安全更新,更新了一处拒绝服务漏洞(CVE-2021-42340).攻击者可以通过该漏洞进行拒绝服务攻击.建议广大用户及时升级至最新版本. 1 ...

  2. Springboot内嵌tomcat

    Springboot内嵌tomcat 前言 一.依赖引入starter-web 二.源码截图 tomcat 如何内嵌 三.springboot 如何启动tomcat 前言 一.依赖引入starter- ...

  3. 总结:SpringBoot内嵌Tomcat原理

    一.介绍 一般我们启动web服务都需要单独的去安装tomcat,而Springboot自身却直接整合了Tomcat,什么原理呢? 二.原理 SpringBoot应用只需要引入spring-boot-s ...

  4. tomcat start 无法启动_解密Springboot内嵌Tomcat

    Springboot简介 相信大多数开发者对Springboot比较熟悉了,它能够快速地创建一个spring应用,能够完全摒弃XML的配置方式,并且内嵌了Tomcat.Jetty这样的Servlet容 ...

  5. springboot内嵌Tomcat启动失败

    问题描述 开发需求期间引入友军的二方包,导致服务启动失败,失败日志如下 java.lang.reflect.InvocationTargetExceptionat sun.reflect.Native ...

  6. 解密Springboot内嵌Tomcat

    Springboot简介 相信大多数开发者对Springboot比较熟悉了,它能够快速地创建一个spring应用,能够完全摒弃XML的配置方式,并且内嵌了Tomcat.Jetty这样的Servlet容 ...

  7. SpringBoot内嵌Tomcat原理

    1.SpringBoot对SpringMVC的支持 对于一个 SpringBoot web 工程来说,一个主要的依赖标志就是有 spring-boot-starter-web 这个 starter , ...

  8. springboot内嵌tomcat调优

    在springboot-configuration-metadata.json文件下面,有很多属于springboot得喷子hi属性,以下为tomcat的默认配置属性: server.tomcat.a ...

  9. EmbeddedServletContainerException: Unable to start embedded Tomcat 内嵌Tomcat启动失败

    这个问题很莫名其妙,早上项目运行的还好好的,下午再跑起来就直接报错了 爆粗信息大概就是项目启动的时候会刷新容器时在创建内嵌servlet容器的时候出错了 在网上搜了很多方法,有这么几种说法 1.端口被 ...

最新文章

  1. MySQL:一个死锁分析 (未分析出来的死锁)
  2. 未能加载文件或程序集“Autofac, Version=3.4.0.0,
  3. php 给html 赋值,PHP+JavaScript+HTML变量之间赋值及传递
  4. python中3 and not 5_python中not、and和or的优先级与详细用法介绍
  5. 北斗形变监测系统_一款基于北斗卫星定位边坡表面位移监测系统
  6. 2021年中国充油散热器市场趋势报告、技术动态创新及2027年市场预测
  7. Sitecore 8.2 页面架构设计:模板与组件
  8. 讨论CGContextDrawImage
  9. 一组开源asp.net用户控件
  10. C#进阶系列——WebApi 路由机制剖析:你准备好了吗?
  11. 【第十届“泰迪杯”数据挖掘挑战赛】C题:疫情背景下的周边游需求图谱分析 问题二方案及Python实现
  12. bochs运行xp_bochs xp镜像
  13. 发光二极管pcb封装图画法_电子元器件认识与使用ZD43 | 贴片74HC138 原理图PCB库 封装尺寸 | 视频教程...
  14. Unity下落式音游实现——(5)根据音乐生成滑块
  15. 鸡啄米:C++编程入门系列之六(算法的基本控制结构之选择结构)
  16. java 自然周_java 使用Calendar类计算每月有多少自然周,并输出每周的开始和结束日期...
  17. IDEA-局部变量、成员变量
  18. 制作独特彩妆美女模特头像照片的PS教程
  19. Leetcode_96_Unique Binary Search Trees
  20. 中国信通院的星火链主链支持与以太链(测试网)交互

热门文章

  1. 花之语第一期:山茶花
  2. Gradle:执行命令时指定 JDK 版本
  3. Unity 角色控制器重复使用Ragdoll布娃娃系统,动画控制和布娃娃状态切换
  4. html 调用手机短信,innerHTML应用模拟手机短信发送
  5. 基于S-FFT的衍射计算
  6. 钱诚10.18黄金实时趋势分析、原油价格涨跌分析及操作建议
  7. inspect python_python inspect模块
  8. offsetTop、offsetLeft、offsetWidth、offsetHeight
  9. Tomcat服务器Servlet入门笔记
  10. Xyplayer X3 正式版