Spring Boot启动流程

1. 启动类与main方法

  • 入口点:Spring Boot应用通常有一个带有@SpringBootApplication注解的主类,并包含一个public static void main(String[] args)方法。
    • @SpringBootApplication是一个组合注解,包含了:
      • @Configuration: 标记该类为配置类。
      • @EnableAutoConfiguration: 自动根据classpath中的依赖进行配置。
      • @ComponentScan: 自动扫描指定包及其子包下的组件(如@Component@Service@Repository@Controller等)。
@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}
}

2. 创建SpringApplication实例

  • 构造函数
    • 推断应用类型:检查classpath中是否存在特定的类(如Servlet、Reactive相关的类),以确定是Servlet还是Reactive应用。
    • 加载初始器和监听器:从META-INF/spring.factories文件中加载默认的ApplicationContextInitializerApplicationListener

3. SpringApplication.run() 方法执行

环境准备
  • 创建并配置Environment:基于命令行参数、系统属性、环境变量等初始化Environment对象。
    • 可以通过--spring.config.locationSPRING_CONFIG_LOCATION环境变量指定外部配置文件的位置。
  • 触发事件:发布ApplicationEnvironmentPreparedEvent事件,允许外部工具或开发者自定义环境设置。
    • 可以通过实现ApplicationListener<ApplicationEnvironmentPreparedEvent>来自定义逻辑。
打印Banner
  • 如果启用了banner,则显示项目启动的图形化标识。
    • 可以通过设置spring.main.banner-modeoff来关闭banner。
创建ApplicationContext
  • 根据应用类型选择合适的ApplicationContext实现(例如,对于Web应用通常是AnnotationConfigServletWebServerApplicationContext)。
    • 对于非Web应用,可能是AnnotationConfigApplicationContext
加载Sources
  • 将所有指定的source(通常是带有@Configuration注解的类)注册到ApplicationContext中。
    • 这包括了自动扫描到的组件和显式声明的配置类。
刷新上下文前的准备工作
  • 触发ApplicationContextInitializedEvent事件。
  • 调用所有的ApplicationContextInitializer进行额外的配置。
    • 这些initializer可以在刷新之前对context进行进一步的定制。

4. ApplicationContext刷新过程

BeanFactory准备
  • 设置bean工厂的各种属性,包括转换服务、属性编辑器等。
    • 配置了诸如PropertyEditorRegistrar等用于处理属性值转换的机制。
BeanDefinition加载
  • 扫描classpath:寻找带有@Component@Service@Repository@Controller等注解的类,并将其注册为bean definitions。
    • 使用ClassPathScanningCandidateComponentProvider扫描指定包下的组件。
    • 条件注解(如@ConditionalOnClass@ConditionalOnMissingBean等)确保仅在满足特定条件时才生效。
自动配置
  • 自动配置机制:通过@EnableAutoConfiguration触发自动配置过程。它会根据classpath中的依赖自动配置相应的beans。
    • 自动配置类位于spring-boot-autoconfigure模块中,它们通过spring.factories文件被发现并加载。
    • 每个自动配置类都可能有条件注解,确保仅在满足特定条件时才生效。
BeanFactoryPostProcessor执行
  • 处理各种后处理器,如PropertySourcesPlaceholderConfigurer用于解析占位符。
    • 解析${...}形式的属性值,替换为实际值。
Bean实例化
  • 根据bean definitions实例化单例bean,并进行依赖注入。
    • 初始化bean时,可能还会执行一些生命周期回调方法,如@PostConstruct标注的方法。
    • 如果需要AOP代理,则在此阶段生成代理对象。

5. 刷新完成后的工作

  • 触发ContextRefreshedEvent:表示ApplicationContext已完全刷新。
  • 执行CommandLineRunner/ApplicationRunner beans:如果有任何实现了CommandLineRunnerApplicationRunner接口的beans,它们的方法会被调用。
    • 这些runner可以用来执行最后的初始化操作。

6. 应用就绪

  • 触发ApplicationReadyEvent:表示应用已经准备好接收请求或执行预定的任务。
  • 开启web服务器:如果是Web应用,此时嵌入式的Tomcat服务器将会启动,并开始监听HTTP请求。

7. 错误处理

  • 错误处理机制:Spring Boot提供了强大的错误处理机制,包括但不限于自定义错误页面、全局异常处理器等,以增强应用的健壮性。
    • 可以通过实现ErrorController来自定义错误页面。
    • 使用@ControllerAdvice@ExceptionHandler来处理全局异常。

额外细节

  • 外部化配置:支持多种方式的外部化配置,如命令行参数、环境变量、properties/yaml文件等。

    • 可以通过application.propertiesapplication.yml文件进行配置。
    • 支持使用@Value注解直接注入配置值。
    • 可以通过spring.profiles.active指定激活的profile,从而加载不同的配置。
  • 健康检查和度量:通过Actuator模块提供的端点,可以监控应用的健康状况和性能指标。

    • 提供了诸如/actuator/health/actuator/metrics等端点。
    • 可以自定义健康指示器(Health Indicator)来扩展健康检查功能。
  • 日志配置:Spring Boot默认支持多种日志框架,并可以通过简单的配置定制日志级别和输出格式。

    • 支持Logback、Log4j2等日志框架,默认使用Logback。
    • 可以通过logging.level.*=DEBUG等配置项调整日志级别。

关键技术细节

  • 条件注解:如@ConditionalOnClass@ConditionalOnMissingBean等,使得Spring Boot能够根据当前环境动态地启用或禁用某些配置。
  • 事件驱动模型:Spring Boot在整个启动过程中使用了大量的事件发布和监听机制,这使得开发者可以在应用启动的不同阶段插入自定义逻辑。
    • 例如,可以通过实现ApplicationListener<ApplicationStartedEvent>来自定义启动逻辑。

示例代码片段

以下是一个更完整的示例,展示了如何使用Spring Boot的基本结构,并结合了一些高级特性和配置:

@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {SpringApplication app = new SpringApplication(DemoApplication.class);// 关闭bannerapp.setBannerMode(Banner.Mode.OFF);// 添加自定义的ApplicationContextInitializerapp.addInitializers(new MyCustomApplicationContextInitializer());app.run(args);}
}@Component
public class MyCommandLineRunner implements CommandLineRunner {@Overridepublic void run(String... args) throws Exception {System.out.println("MyCommandLineRunner executed");}
}@Configuration
public class MyCustomConfig {@Bean@ConditionalOnMissingBean(name = "customBean")public String customBean() {return "This is a custom bean";}
}// 自定义健康检查
@Component
public class CustomHealthIndicator extends AbstractHealthIndicator {@Overrideprotected void doHealthCheck(Health.Builder builder) throws Exception {builder.up().withDetail("custom", "Everything is OK!");}
}// 全局异常处理器
@ControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(value = Exception.class)public ResponseEntity<Object> exception(Exception exception) {return new ResponseEntity<>("An error occurred: " + exception.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);}
}// 自定义ApplicationContextInitializer
public class MyCustomApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {@Overridepublic void initialize(ConfigurableApplicationContext applicationContext) {ConfigurableEnvironment environment = applicationContext.getEnvironment();// 自定义环境配置Map<String, Object> map = new HashMap<>();map.put("my.custom.property", "customValue");environment.getPropertySources().addFirst(new MapPropertySource("customProperties", map));}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/74086.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设计模式——设计模式理念

文章目录 参考&#xff1a;[设计模式——设计模式理念](https://mp.weixin.qq.com/s/IEduZFF6SaeAthWFFV6zKQ)参考&#xff1a;[设计模式——工厂方法模式](https://mp.weixin.qq.com/s/7tKIPtjvDxDJm4uFnqGsgQ)参考&#xff1a;[设计模式——抽象工厂模式](https://mp.weixin.…

Android 16开发实战指南|锁屏交互+Vulkan优化全解析

一、环境搭建与项目初始化 1. 安装Android Studio Ladybug 下载地址:Android Studio官网关键配置: # 安装后立即更新SDK SDK Manager → SDK Platforms → 安装Android 16 (Preview) SDK Manager → SDK Tools → 更新Android SDK Build-Tools至34.0.0 # 通过命令行安装SDK组…

selenium应用测试场景

Selenium 是主流的 Web 自动化测试框架&#xff0c;主要用于基于浏览器的 Web 应用测试。以下是 Selenium 的典型测试场景和适用场景&#xff0c;以及与 Appium 的对比&#xff1a; 1. Selenium 的核心测试场景 (1) Web 功能测试&#xff08;Functional Testing&#xff09; 表…

[Vue]生命周期

在编程领域生命周期指的即一个对象从创建到销毁的过程。 Vue的生命周期大概分为四个阶段&#xff1a; 创建阶段 在该阶段&#xff0c;vue的主要工作是为渲染模板做准备工作。比如处理data中的数据&#xff0c;使其变为响应式数据。在html中普通的数据往往不具备响应式等一系列…

低代码平台,智慧城市建设的加速器

随着城市数字化进程加速&#xff0c;智慧停车、智慧交通、城市数据治理等领域对技术敏捷性和开发效率的需求日益凸显。低代码平台凭借其可视化开发、模块化设计和快速部署能力&#xff0c;正在成为推动城市治理智能化升级的核心工具。本文将通过低代码在智慧城市建设上应用的展…

14 配置Hadoop集群-配置历史和日志服务

第一课时 一、导入 前面的课程我们搭建了hadoop集群&#xff0c;并成功启动了它&#xff0c;接下来我们看看如何去使用集群。 测试的内容包括&#xff1a;1.上传文件&#xff0c;2.下载文件&#xff0c;3.运行程序 二、授新 &#xff08;一&#xff09;配置运行任务的历史服务器…

0102-web架构网站搭建-基础入门-网络安全

文章目录 1. 常规2 站库分离3 前后端分离4 集成环境5 docker6 分配站结语 1. 常规 结构&#xff1a;源码数据都在同服务器 影响&#xff1a;无&#xff0c;常规安全测试手法 2 站库分离 结构&#xff1a;源码和数据库不在同服务器 存储&#xff1a;其他服务器上数据库或者…

【分布式系统】-2-GFS

MIT的【分布式系统课程】学习记录 内容纯属个人学习过程中的笔记记录&#xff0c;如果有侵权现象请留言&#xff0c;会立刻删除 分布式存储系统的难点&#xff1a; 设计大型存储系统的出发点&#xff1a;利用数百台计算机资源同时完成大量工作&#xff0c;达到性能加成 如何做…

黑盒测试的场景法(能对项目业务进行设计测试点)

定义: 通过运用场景来对系统的功能点或业务流程的描述&#xff0c;设计用例遍历场景&#xff0c;验证软件系统功能的正确性从而提高测试效果的一种方法。 场景法一般包含基本流和备用流。 基本流:软件功能的正确流程&#xff0c;通常一个业务只存在一个基本流且基本流有一个…

22 安装第三方包

一、什么是第三方包 在 Python 的世界里&#xff0c;包就像是一个个功能强大的工具箱&#xff0c;它将多个 Python 模块收纳其中&#xff0c;而每个模块又蕴含着丰富多样的具体功能。可以说&#xff0c;一个包就是一系列同类功能的集合体&#xff0c;它们就像紧密协作的团队&a…

MyBatisPlus不等于如何使用

在 MyBatis Plus 中&#xff0c;ne 方法用于构建不等于条件的 SQL 查询。以下是 ne 方法的详细用法&#xff1a; 基本用法 ne 方法可以用于 QueryWrapper 或 LambdaQueryWrapper 中&#xff0c;用于指定某个字段的值不等于指定的值。它对应于 SQL 中的 ! 或 <> 操作符。 …

[学术][人工智能] 001_什么是神经网络?

神经网络是一种模拟生物神经系统的计算模型&#xff0c;具有广泛的应用和重要的研究价值。以下将从不同方面详细介绍神经网络。 一、神经网络的发展历程 20 世纪 60 年代&#xff0c;Hubel 和 Wiesel 在研究猫脑皮层中发现了用于局部敏感和方向选择的神经元结构&#xff0c;卷积…

Unity3D仿星露谷物语开发32之地面属性决定角色动作

1、目标 根据地面属性&#xff08;diggable, canDropItem, canPlaceFurniture, isPath, isNPCObstacle&#xff09;决定角色进行何种操作。比如没有canDropItem属性的地面&#xff0c;则不能放置物体。 2、优化保存Item数据 PS&#xff1a;这个是对已有代码的优化&#xff0…

031-valgrind

valgrind 以下是从原理到代码实现、参数优化及结果分析的Valgrind技术调研报告&#xff0c;结合C示例和可视化工具使用说明&#xff1a; 一、Valgrind核心原理与架构 1.1 系统架构 #mermaid-svg-xIgV3fg90dGhEEq4 {font-family:"trebuchet ms",verdana,arial,sans-…

C/C++蓝桥杯算法真题打卡(Day12)

一、P8752 [蓝桥杯 2021 省 B2] 特殊年份 - 洛谷 算法代码&#xff1a; #include<bits/stdc.h> using namespace std; int cnt;int main() {int i1;while(i<5){int num;cin>>num;string string_numto_string(num);if(string_num[0]string_num[2]&&str…

MySQL 复制与主从架构(Master-Slave)

MySQL 复制与主从架构&#xff08;Master-Slave&#xff09; MySQL 复制与主从架构是数据库高可用和负载均衡的重要手段。通过复制数据到多个从服务器&#xff0c;既可以实现数据冗余备份&#xff0c;又能分担查询压力&#xff0c;提升系统整体性能与容错能力。本文将详细介绍…

《大模型部署》——ollama下载及大模型本地部署(详细快速部署)

ollama Ollama 是一款开源跨平台的大语言模型&#xff08;LLM&#xff09;运行工具&#xff0c;旨在简化本地部署和管理 AI 模型的流程。 下载ollama 进入官网下载https://ollama.com/ 选择需要的系统下载 下载完成后直接进行安装 下载大模型 选择想要部署的模型&#…

Java关于包和final

什么是包&#xff1f; 包就是文件夹。用来管理等各种不同功能的java类&#xff0c;方便后期代码维护 包名的规则&#xff1a;公司域名反写包的作用&#xff0c;需要全部英文小写&#xff0c;见名知意。例如&#xff1a;com.pdsu.domain package com.pdsu.demain;public class…

数据层的基本操作

1.数据层的更名: Arcmap内容列表中,数据框所包含的每个图层及每个图层所包含的一系列地理要素,都有相应的描述字符与之对应.默认情况下,添加进地图的图层是以其数据源的名字命名的,而地理要素的描述就是要素类型字段取值.由于这些命名影响到用户对数据的理解和地图输出时的图例…

Vue舞台剧

Vue 的舞台剧比喻 &#x1f3ad;&#xff08;完整表格版&#xff09; Vue 结构及路由管理 Vue 结构比喻&#xff08;舞台剧&#xff09;&#x1f3ad;作用index.html空白场地 &#x1f3df;️Vue 负责填充内容&#xff0c;提供 #app 容器&#xff0c;等待演出开始。main.js导…