Spring Boot 启动流程及配置类解析原理

Spring Boot 是一个基于 Spring 框架的开源框架,旨在简化 Spring 应用的配置和部署。通过提供约定优于配置的原则,Spring Boot 大大降低了 Java 企业级应用的开发复杂度。本文将详细介绍 Spring Boot 的启动流程及其配置类的解析原理,帮助开发者深入理解 Spring Boot 的工作机制。

一、Spring Boot 启动流程

1.1 启动入口

Spring Boot 应用的启动入口通常是一个带有 main 方法的类,该类被注解为 @SpringBootApplication。该注解实际上是一个复合注解,包含了以下三个注解:

  • @Configuration:指示该类是一个 Spring 配置类。
  • @EnableAutoConfiguration:启用 Spring Boot 的自动配置机制。
  • @ComponentScan:启用组件扫描,以自动发现并注册 Spring 组件。

以下是一个简单的 Spring Boot 启动类示例:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class MyApplication {public static void main(String[] args) {SpringApplication.run(MyApplication.class, args);}
}
​

1.2 SpringApplication 的启动过程

在 main 方法中,调用了 SpringApplication.run() 方法,该方法是 Spring Boot 应用启动的核心。其主要流程如下:

  1. 创建 SpringApplication 实例:
    SpringApplication 是启动 Spring Boot 应用的核心类。它负责启动应用的上下文,并执行所有必要的初始化步骤。

    SpringApplication application = new SpringApplication(MyApplication.class);
    ​
    
  2. 准备上下文:
    在 run 方法中,首先会准备一个 ApplicationContext(默认是 AnnotationConfigApplicationContext 或 WebApplicationContext),并将主类传入。

  3. 加载配置:
    根据 @SpringBootApplication 中的设置,加载应用的配置文件(如 application.properties 或 application.yml),并将其转化为配置属性。

  4. 执行自动配置:
    通过 @EnableAutoConfiguration 注解,Spring Boot 会自动装配必要的组件。例如,如果存在数据库驱动,则自动配置 DataSource。

  5. 启动应用上下文:
    启动 ApplicationContext,完成 Bean 的初始化和依赖注入。

  6. 触发 ApplicationRunner 和 CommandLineRunner:
    如果定义了 ApplicationRunner 或 CommandLineRunner 接口的实现类,Spring Boot 会在应用启动后自动调用它们。

1.3 SpringApplication.run() 的关键步骤

以下是 SpringApplication.run() 方法中的关键步骤详细解析:

public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {SpringApplication application = new SpringApplication(primarySource);return application.run(args);
}
​
  1. 构造 SpringApplication 实例:
    primarySource 是启动类,用于加载上下文。
  2. 准备环境:
    调用 prepareEnvironment() 方法,设置应用的环境(如 Environment 和 ApplicationArguments)。
  3. 创建应用上下文:
    调用 createApplicationContext() 方法,根据应用类型创建相应的 ApplicationContext。
  4. 准备上下文:
    调用 prepareContext() 方法,配置上下文的属性和 Bean。
  5. 刷新上下文:
    调用 refreshContext() 方法,初始化和刷新上下文。
  6. 调用应用的生命周期事件:
    触发 ApplicationStartedEvent 和 ApplicationReadyEvent 事件。

1.4 事件机制

在 Spring Boot 启动过程中,会触发多个事件,例如 ApplicationStartedEvent、ApplicationEnvironmentPreparedEvent 和 ApplicationReadyEvent。开发者可以通过实现 ApplicationListener 接口来监听这些事件。

二、Spring Boot 配置类解析原理

2.1 配置类的定义

在 Spring Boot 中,配置类通常是使用 @Configuration 注解标记的类。这些类用于定义 Bean,进行依赖注入和其他配置信息。以下是一个配置类的示例:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MyConfig {@Beanpublic MyService myService() {return new MyService();}
}
​

2.2 配置类的解析过程

当 Spring Boot 启动时,配置类的解析过程主要涉及以下步骤:

  1. 组件扫描:
    在 @SpringBootApplication 注解的类中,会进行组件扫描,寻找所有的 @Configuration 注解。
  2. 创建 ConfigurationClassParser 实例:
    ConfigurationClassParser 是解析配置类的核心类,负责分析和处理所有的配置类。
  3. 解析配置类:
    ConfigurationClassParser 会解析配置类中的 @Bean 方法,并生成相应的 BeanDefinition。
  4. 注册 BeanDefinition:
    将解析得到的 BeanDefinition 注册到 BeanDefinitionRegistry 中,供后续使用。

2.3 Bean 的创建与注入

当需要使用某个 Bean 时,Spring 容器会根据 BeanDefinition 创建 Bean 实例,并进行依赖注入。

  1. 获取 BeanDefinition:
    在调用 Bean 的时候,Spring 会从 ApplicationContext 中获取对应的 BeanDefinition。
  2. 实例化 Bean:
    使用 BeanFactory 中的 doGetBean() 方法,创建 Bean 实例。
  3. 依赖注入:
    Spring 会自动识别 Bean 的依赖关系,进行依赖注入。

2.4 注解的作用

在配置类中,常用的注解包括:

  • @Bean:用于定义 Bean 方法,返回的对象将被注册为 Spring 的 Bean。
  • @Configuration:标识配置类,表示该类可以包含多个 @Bean 方法。
  • @Conditional:用于条件化 Bean 的创建,根据条件决定是否创建 Bean。

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

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

相关文章

Flask 核心概念速览:路由、请求、响应与蓝图

一、路由参数与请求方法 Flask 路由允许定义多种参数类型,并通过 methods 属性限制请求方法。 1. 路由参数类型: 除了默认的 string,Flask 还支持: int: 匹配整数,自动转换为 Python int 类型。非数字输入会返回 404。 float: 匹配浮点数,自动转换为 Python float 类型…

Beckhoff(倍福)PLC 顺控程序转换条件解读

一、请求机器人上件步 二、程序代码解释:1、程序代码1&#xff1a; 1、程序代码&#xff1a; fbVar_TonDelay2(IN : (bInPartPresentLeft AND bInPartPresentRight), PT : T#100MS);(* Go to the next step *) stVar_SEQ.bTOK : stVar_SEQ.bRELEASE AND(stGV_SYS_ELEMENTS.ar…

KITTI数据集(计算机视觉和自动驾驶领域)

KITTI&#xff08;Karlsruhe Institute of Technology and Toyota Technological Institute at Chicago&#xff09;数据集是计算机视觉和自动驾驶领域中最广泛使用的基准数据集之一。它由德国卡尔斯鲁厄理工学院和美国芝加哥丰田技术研究所联合发布&#xff0c;旨在推动自动驾…

echarts在uniapp中使用安卓真机运行时无法显示的问题

文章目录 一、实现效果二、话不多说&#xff0c;上源码 前言&#xff1a;我们在uniapp中开发的时候&#xff0c;开发的时候很正常&#xff0c;echarts的图形在h5页面上也是很正常的&#xff0c;但是当我们打包成安卓app或者使用安卓真机运行的时候&#xff0c;图形根本就没有渲…

C#使用MindFusion.Diagramming框架绘制流程图(1):基础类型

MindFusion.Diagramming框架 在C#中使用MindFusion.Diagramming.dll库来创建图表和图形界面&#xff0c;可以让你构建出丰富和交互式的图形应用。MindFusion.Diagramming 是一个强大的库&#xff0c;支持创建各种类型的图表&#xff0c;例如流程图、网络图、组织结构图等。 M…

LangChain【6】之输出解析器:结构化LLM响应的关键工具

文章目录 一 LangChain输出解析器概述1.1 什么是输出解析器&#xff1f;1.2 主要功能与工作原理1.3 常用解析器类型 二 主要输出解析器类型2.1 Pydantic/Json输出解析器2.2 结构化输出解析器2.3 列表解析器2.4 日期解析器2.5 Json输出解析器2.6 xml输出解析器 三 高级使用技巧3…

Spring Boot项目中JSON解析库的深度解析与应用实践

在现代Web开发中&#xff0c;JSON&#xff08;JavaScript Object Notation&#xff09;作为轻量级的数据交换格式&#xff0c;已成为前后端通信的核心桥梁。Spring Boot作为Java生态中最流行的微服务框架&#xff0c;提供了对多种JSON库的无缝集成支持。本文将深入探讨Spring B…

OPenCV CUDA模块光流------高效地执行光流估计的类BroxOpticalFlow

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::cuda::BroxOpticalFlow 是 OpenCV CUDA 模块中实现Brox光流算法的类。该类用于在 GPU 上高效地计算两帧图像之间的稠密光流&#xff08;Dens…

视觉分析在人员行为属性检测中的应用

基于视觉分析的人员行为属性检测方案 一、背景与需求分析 在工业生产、建筑施工、公共安全等领域&#xff0c;人员行为属性的合规性检测是保障安全生产的关键环节。例如&#xff0c;工地工人未佩戴安全帽、厨房人员未佩戴手套、作业现场人员使用手机等行为&#xff0c;均可能…

Linux--进程的程序替换

问题导入&#xff1a; 前面我们知道了&#xff0c;fork之后&#xff0c;子进程会继承父进程的代码和“数据”&#xff08;写实拷贝&#xff09;。 那么如果我们需要子进程完全去完成一个自己的程序怎么办呢&#xff1f; 进程的程序替换来完成这个功能&#xff01; 1.替换原理…

场景题-3

如何实现一个消息队列 拆解分析主流的几种消息队列 1、基本架构 生产者Producer、消费者Consumer、Broker&#xff1a;生产者发送消息&#xff0c;消费者接受消息&#xff0c;Broker是服务端&#xff0c;处理消息的存储、备份、删除和消费关系的维护。 主题和分区&#xff…

vue2 项目中 npm run dev 运行98% after emitting CopyPlugin 卡死

今天在运行项目时&#xff0c;发现如下问题&#xff1a; 开始以为是node_modules依赖的问题&#xff0c;于是重新 npm install&#xff0c;重启项目后还是未解决。 在网上找了一圈发现有人说是 require引入图片地址没有写。在我的项目中排查没有这个问题&#xff0c;最后发现某…

73 LV的使用(XFS文件系统)

四 LV的使用 先创建一个LV01 lvcreate -L 10G lv01 datavg Logical volume "lv01" created. 将创建出来的LV01进行格式化 mkfs.xxx LV的名称(绝对路径) 绝对路径的组成:/dev/你创建VG的名字/LV的名字 mkfs.xfs /dev/datavg/lv01 挂载你的LV…

mybatis中判断等于字符串的条件怎么写

mybatis中判断等于字符串的条件怎么写_mybatis 等于字符串-CSDN博客 因为mybatis映射文件&#xff0c;是使用的ognl表达式&#xff0c;ognl是java语言&#xff08;强类型语言&#xff09;&#xff0c;会把‘X’解析成字符&#xff0c;而不是字符串。 所以比较字符串相等使用是…

C语言实现绝对值差值函数

在C语言中&#xff0c;可以编写一个函数来计算两个数的差值的绝对值。以下是一个简单的实现&#xff1a; #include <stdio.h> #include <stdlib.h> // 用于abs函数&#xff08;如果需要&#xff09; // 方法1&#xff1a;使用标准库函数 int absoluteDifference1…

Three.js中AR实现详解并详细介绍基于图像标记模式AR生成的详细步骤

文档地址 Three.js中AR实现详解 以下是Three.js中实现AR功能的详细解析&#xff0c;涵盖技术原理、实现步骤、核心组件及优化策略&#xff1a; &#x1f9e9; 一、技术基础 AR.js框架的核心作用 AR.js是Three.js实现AR的基石&#xff0c;提供以下核心能力&#xff1a; 多模…

Vue3.5 企业级管理系统实战(二十三):权限指令

在实际应用场景中&#xff0c;常常需要依据用户角色对按钮的操作权限实施控制。实现这一控制主要有两种方式&#xff1a;一种是借助前端指令基于角色进行权限管控&#xff0c;另一种是通过后台返回对应的权限属性来实现精细化控制。本文聚焦于前端权限指令展开探讨。 1 权限指…

软考 系统架构设计师系列知识点之杂项集萃(81)

接前一篇文章&#xff1a;软考 系统架构设计师系列知识点之杂项集萃&#xff08;80&#xff09; 第145题 商业智能是企业对商业数据的搜集、管理和分析的系统过程&#xff0c;主要技术包括&#xff08;&#xff09;。 A. 数据仓库、联机分析和数据挖掘 B. 数据采集、数据清洗…

深入浅出Java ParallelStream:高效并行利器还是隐藏的陷阱?

在Java 8带来的众多革新中&#xff0c;Stream API彻底改变了我们对集合操作的方式。而其中最引人注目的特性之一便是parallelStream——它承诺只需简单调用一个方法&#xff0c;就能让数据处理任务自动并行化&#xff0c;充分利用多核CPU的优势。但在美好承诺的背后&#xff0c…

SQL Transactions(事务)、隔离机制

目录 Why Transactions? Example: Bad Interaction Transactions ACID Transactions COMMIT ROLLBACK How the Transaction Log Works How Data Is Stored Example: Interacting Processes Interleaving of Statements Example: Strange Interleaving Fixing the…