SpringBoot2.x(五)启动方式启动原理
启动方式jar包启动需引入springboot应用maven构建插件主要用来指定应用启动类build plugins plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId /plugin /plugins /buildjar包目录结构example.jar | -META-INF | -MANIFEST.MF -org | -springframework | -boot | -loader | -spring boot loader classes -BOOT-INF -classes | -mycompany | -project | -YourClasses.class -lib -dependency1.jar -dependency2.jarmvn spring-boot:run如果项目是maven目录结构可以进入项目根目录输入maven命令mvn 项目名:run来启动部署war包到tomcat9在pom.xml中设置打包方式为war在pom.xml的build节点下指定项目名如finalNamespringboot-demo/finalName更改启动类如下:public class Application extends SpringBootServletInitializer { Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(XdclassApplication.class); } public static void main(String[] args) throws Exception { SpringApplication.run(XdclassApplication.class, args); } }打包mvn install将target中的war包放入tomcat9并启动tomcat访问 http://localhost:8080/springboot-demo/testExstartup.bat闪退怎么办如果你的OS是windows也许你碰到过通过startup.bat启动tomcat命令行闪退的情况。那通常是一些配置异常导致的你可以在该文件的末尾加上一句pause;该命令行遇到异常时就会暂停而不会闪退至此你可以从中发现异常点。linux用户在tomcat/logs/catlina.out查看tomcat启动日志启动容器和第三方测试数据常见的javaweb的启动容器有tomcat、jetty、undertowJmterJmter是一个第三方测试容器性能的工具有兴趣的可以参见 https://examples.javacodegeeks.com/enterprise-java/spring/tomcat-vs-jetty-vs-undertow-comparison-of-spring-boot-embedded-servlet-containers/ 自学一下。启动原理概述springboot应用启动大致分两步从SpringApplication.run(Application.class, args);追溯到run(new Class?[] { primarySource }, args)再到new SpringApplication(primarySources).run(args)可发现分为以下两步1.SpringApplication(primarySources)此步主要为应用启动做准备如判断应用类型是否为web应用、初始化spring工厂实例、初始化监听器public SpringApplication(Class?... primarySources) { this(null, primarySources); }public SpringApplication(ResourceLoader resourceLoader, Class?... primarySources) { //null this.resourceLoader resourceLoader; //断言启动类不为空 Assert.notNull(primarySources, PrimarySources must not be null); this.primarySources new LinkedHashSet(Arrays.asList(primarySources)); this.webApplicationType deduceWebApplicationType(); setInitializers((Collection) getSpringFactoriesInstances( ApplicationContextInitializer.class)); setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); this.mainApplicationClass deduceMainApplicationClass(); }webApplicationTypeprivate 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; } } return WebApplicationType.SERVLET; }这里会判断当前应用是否为web应用查看WebApplicationType可知有三种枚举类型分别是NONE不是web应用、SERVELT需要tomcat、jetty或undertow这样的servelt容器、REACTIVE这个跟之后涉及到的WebFlux函数式编程有关。setInitializers加载用来初始化spring容器的工厂实例。这些工厂类位于META-INF/spring.factories中你能在spring-boo.jar或spring-boot-devtool.jar中看到private T CollectionT getSpringFactoriesInstances(ClassT type,Class?[] parameterTypes, Object... args) { ClassLoader classLoader Thread.currentThread().getContextClassLoader(); // Use names and ensure unique to protect against duplicates SetString names new LinkedHashSet( SpringFactoriesLoader.loadFactoryNames(type, classLoader)); ListT instances createSpringFactoriesInstances(type, parameterTypes,classLoader, args, names); AnnotationAwareOrderComparator.sort(instances); return instances; } private T ListT createSpringFactoriesInstances(ClassT type, Class?[] parameterTypes, ClassLoader classLoader, Object[] args, SetString names) { ListT instances new ArrayList(names.size()); for (String name : names) { try { Class? instanceClass ClassUtils.forName(name, classLoader); Assert.isAssignable(type, instanceClass); Constructor? constructor instanceClass.getDeclaredConstructor(parameterTypes); T instance (T) BeanUtils.instantiateClass(constructor, args); instances.add(instance); } catch (Throwable ex) { throw new IllegalArgumentException( Cannot instantiate type : name, ex); } } return instances; }deduceMainApplicationClass()该方法遍历栈踪迹去找一个包含叫main字符串的栈元素来取得应用的启动类。private Class? deduceMainApplicationClass() { try { StackTraceElement[] stackTrace new RuntimeException().getStackTrace(); for (StackTraceElement stackTraceElement : stackTrace) { if (main.equals(stackTraceElement.getMethodName())) { return Class.forName(stackTraceElement.getClassName()); } } } catch (ClassNotFoundException ex) { // Swallow and continue } return null; }2.run(String... args)public ConfigurableApplicationContext run(String... args) { StopWatch stopWatch new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context null; CollectionSpringBootExceptionReporter exceptionReporters new ArrayList(); configureHeadlessProperty(); //获取运行时监听并启动 SpringApplicationRunListeners listeners getRunListeners(args); listeners.starting(); try { ApplicationArguments applicationArguments new DefaultApplicationArguments(args); ConfigurableEnvironment environment prepareEnvironment(listeners,applicationArguments); configureIgnoreBeanInfo(environment); Banner printedBanner printBanner(environment); context createApplicationContext(); exceptionReporters getSpringFactoriesInstances( SpringBootExceptionReporter.class, new Class[] { ConfigurableApplicationContext.class }, context); prepareContext(context, environment, listeners, applicationArguments, printedBanner); refreshContext(context); afterRefresh(context, applicationArguments); stopWatch.stop(); ...stopWatchstopWatch主要用来计时可以提取反映容器性能指标printBanner准备要打印的bannercreateApplicationContext创建spring容器启动原理尚未明朗有待后续学习更多学习资料搜索

相关新闻

AU-48 双模拟麦多功能降噪回音消除模组:USB回环参考与低阻抗直驱输出设计详解

AU-48 双模拟麦多功能降噪回音消除模组:USB回环参考与低阻抗直驱输出设计详解

一、产品定位与核心定位AU-48 双模拟麦多功能降噪回音消除模组是德宇科创推出的双模拟麦克风输入多功能语音处理模组,专为替代传统A-47模块设计,在保持接口兼容性的同时全面升级了处理能力。AU-48支持模拟麦克风USB双模式,内置AI降噪&#xf…

2026/7/28 14:59:18阅读更多 →
数据结构(19):二叉树的三叉链表表示

数据结构(19):二叉树的三叉链表表示

程序代码&#xff1a; //二叉树的三叉链表存储 #include <stdio.h> #include <stdlib.h> #define max(a, b) a > b ? a : b #define ClearBiTree DestroyBiTree typedef char TElemType;// 二叉树的三叉链表存储表示 typedef struct BiTPNode {TElemType data;…

2026/7/28 14:59:18阅读更多 →
Axure中文语言包终极指南:3分钟让你的原型设计软件说中文

Axure中文语言包终极指南:3分钟让你的原型设计软件说中文

Axure中文语言包终极指南&#xff1a;3分钟让你的原型设计软件说中文 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 你是否在使…

2026/7/28 14:59:18阅读更多 →
库函数和系统调用函数

库函数和系统调用函数

库函数在函数库文件中实现&#xff0c;执行时在用户态执行。 系统调用函数是系统内核向用户用户空间提供的接口&#xff0c;系统调用函数有用户态调用&#xff0c;实现在内核态。 系统调用函数实现原理 系统调用函数出发0x80中断&#xff0c;并且将系统调用号存储在eax寄存器中…

2026/7/28 16:09:42阅读更多 →
《极限竞速》车辆涂装生成算法深度解析与性能优化指南

《极限竞速》车辆涂装生成算法深度解析与性能优化指南

《极限竞速》车辆涂装生成算法深度解析与性能优化指南 【免费下载链接】forza-painter Import images into Forza 项目地址: https://gitcode.com/gh_mirrors/fo/forza-painter Forza Painter 是一款基于几何化算法的开源工具&#xff0c;专门为《极限竞速&#xff1a;地…

2026/7/28 16:09:42阅读更多 →
ES初探!

ES初探!

前言 在上手使用前&#xff0c;需要先了解一些基本的概念。 推荐 可以到 https://www.elastic.co/guide/cn/elasticsearch/guide/current/index.html 阅读《Elastic Search 权威指南》&#xff0c;有非常详细和全面的说明。 ES中的一些概念 index&#xff08;索引&#xff09…

2026/7/28 16:09:42阅读更多 →
TPIC7710EVM评估模块硬件解析与汽车电子驱动设计实践

TPIC7710EVM评估模块硬件解析与汽车电子驱动设计实践

1. 项目概述&#xff1a;TPIC7710EVM评估模块硬件深度解析在汽车电子和嵌入式系统开发领域&#xff0c;尤其是在车身控制、执行器驱动这类对可靠性和实时性要求极高的场景中&#xff0c;一颗芯片的数据手册往往不足以让工程师完全放心。数据手册告诉你它能做什么&#xff0c;但…

2026/7/28 16:09:42阅读更多 →
java学习(88):Charactor包装类

java学习(88):Charactor包装类

//Character包装类 public class test23 {public static void main(String[] args){char chA;//使用构造方法Character obj1new Character(中);//使用静态方法Character obj2Character.valueOf(ch);//获取char值char zhongobj1.charValue();System.out.println(zhong);int reso…

2026/7/28 16:09:42阅读更多 →
2026 AI 搜索范式演进:基于语义向量空间对齐与多 Agent 协同的 GEO 架构设计与平台工程实战

2026 AI 搜索范式演进:基于语义向量空间对齐与多 Agent 协同的 GEO 架构设计与平台工程实战

摘要 随着大语言模型&#xff08;LLM&#xff09;与检索增强生成&#xff08;RAG&#xff09;深度融入信息分发场景&#xff0c;传统依赖倒排索引与关键词堆砌的搜索引擎优化&#xff08;SEO&#xff09;正在向生成式引擎优化&#xff08;GEO&#xff09;全面跃迁。在多 Agent…

2026/7/28 16:07:42阅读更多 →
覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

&#x1f539; 工具基础介绍 OpenClaw 是开源生态中一款实用性较强的本地智能工具&#xff0c;凭借本地离线运行、可视化图形操作和任务自动化三大核心特性&#xff0c;赢得了众多用户的青睐。与普通在线对话AI工具不同&#xff0c;它属于能够直接操控本机软硬件的智能数字员工…

2026/7/28 4:06:39阅读更多 →
伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

所谓液压伺服阀体的精密激光焊接&#xff0c;是用激光束对阀座壳体&#xff08;通常为不锈钢或铝合金&#xff09;进行密封焊接&#xff0c;使阀体在21-35MPa的高压液压油或压缩气体中长期运行而不发生介质泄漏。液压伺服阀是高端液压系统的"大脑"。从航空航天飞行控…

2026/7/28 2:08:06阅读更多 →
D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX&#xff1a;三步实现《暗黑破坏神2》高清宽屏体验的终极指南 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 你是否还在…

2026/7/28 1:38:28阅读更多 →
告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿&#xff01;3步让你的暗影精灵笔记本重获新生 【免费下载链接】OmenSuperHub Control Omen laptop performance, fan speeds, and keyboard lighting, and unlock power limits. 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub 你是否也曾为官方Om…

2026/7/28 0:00:29阅读更多 →
RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

做 RAG 的人应该都踩过这个致命的坑&#xff1a;把几百页的财报、法规、技术手册扔给向量库&#xff0c;问一个具体问题&#xff0c;搜出来的全是沾边但没用的内容 —— 关键信息要么被硬切块拆碎了&#xff0c;要么藏在几十条结果的最下面。语义相似≠真正相关&#xff0c;这个…

2026/7/28 0:00:29阅读更多 →
抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

2026年做短视频运营&#xff0c;从抖音上扒文案早就不是偷偷抄笔记的事了。我刚开始做内容的时候&#xff0c;每天刷半小时抖音&#xff0c;手动把爆款视频的口播敲进备忘录&#xff0c;一条2分钟的视频得花十来分钟&#xff0c;碰到语速快的还要反复回听。后来试了一圈工具&am…

2026/7/28 0:00:29阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时&#xff0c;发现推理速度只有可怜的 1-2 FPS&#xff0c;而别人的演示视频却能跑到 30 FPS 以上&#xff0c;那么问题很可能不在模型本身&#xff0c;而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后&#xff0c;会直接使用官方示例…

2026/7/27 16:57:54阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一&#xff1a;为什么你需要了解 Coze 和 Dify&#xff1f;如果你对 AI 应用开发感兴趣&#xff0c;但一看到“大模型”、“智能体”、“工作流”这些词就头疼&#xff0c;觉得门槛太高&#xff0c;那这篇文章就是为你准备的。很多开发者&#xff0c;包括我自己&#…

2026/7/28 3:17:03阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会&#xff1a;配图一直是个让人头疼的问题。2026年&#xff0c;AI生图工具已经非常成熟了&#xff0c;但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1&#xff1a;速度之王2026年6月11日&#xff0c…

2026/7/28 2:35:58阅读更多 →