springBoot 核心原理

自动配置

包扫描规则:

  • 默认的扫描规则 @SpringBootApplication 标注的类就是主程序类 ,springBoot也只会扫描主程序类所在的包以及下面的子包
  • 也可以自定义声明扫描其他包
    • 使用 @SpringBootApplication(scanBasePackages = “com.test”)
    • 使用@ ComponentScan( “com.test” ) 来指定包扫描路径

Spring Boot的核心注解是哪个

  • @SpringBootApplication 是 Spring Boot 最核心的注解

    • 用在 Spring Boot启动类上,标识这是一个 Spring Boot 应用,用来开启 Spring Boot 的各项能力。

    • 这个注解是 @SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan 这三个注解的组合,也可以用这三个注解来代替 @SpringBootApplication 注解。

  • @SpringBootConfiguration: 组合了@Configuration 注解,实现配置文件的功能。

  • @EnableAutoConfiguration: 打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据源自动配置功能,开启这个注解之后,Spring Boot 就能根据当前类路径下的包或者类来配置 Spring Bean。

  • @ComponentScan: Spring组件扫描,用来代替配置文件中的 component-scan 配置,开启组件扫描,即自动扫描包路径下的 @Component 注解进行注册 bean 实例到 context 中。

  • @Configuration,用来代替 applicationContext.xml 配置文件,所有这个配置文件里面能做到的事情都可以通过这个注解所在类来进行注册。

spring boot的自动配置原理:

  • 每一个stater都会导入 spring-boot-starterspring-boot-starter是所有stater的stater,其中又导入了spring-boot-autoconfigure 其中包含了全场景的自动配置类

  • 但是spring boot默认只扫描主程序下的包及其子包,所以扫不到spring-boot-autoconfigure 下写好的配置,只有导入了对应场景的包,相关的配置类才会存在,对应的功能也就生效了

  • spring boot 主程序的注解 @SpringBootApplication 由三个注解组成

    • @SpringBootConfiguration 声明配置类

    • @ComponentScan 扫描指定的组件包

      • springboot这里排除了已经加载过的配置类和自动配置类,防止重复加载
    • @EnableAutoConfiguration 是spring boot开启自动配置的核心注解

  • 最终达到的效果是,导入对应的stater,在配置文件中配置对应的属性值,就能使用对应组件的功能

EnableAutoConfiguration 用于开启自动配置,包含以下注解

  • @AutoConfigurationPackage(加载自己的组件)

    • 底层是利用 @Import(AutoConfigurationPackages.Registrar.class),把主程序所在的所有组件导入进来,所以springboot默认只扫描主程序所在的包及其子包
  • @Import(AutoConfigurationImportSelector.class) (加载springboot提供的组件)

    • 用于给容器中批量导入组件,springboot 启动时会自动导入spring-boot-autoconfigure 包下 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 内默认的配置文件XXXAutoConfiguration

    • 虽然会一次性导入很多配置,但是这些配置不一定都生效,是按需生效的,每一个自动配置类都有条件注解,以RedisAutoConfiguration为例,想要RedisAutoConfiguration配置类生效,就必须要有RedisOperations.class这个类存在
      请添加图片描述

    • @EnableConfigurationProperties({RedisProperties.class}) 则会开启这个类和配置文件的绑定,同时RedisProperties定义了配置文件中的前缀(spring.data.redis),这样就可以把配置文件中指定前缀的值绑定到配置类中
      请添加图片描述

spring-boot-autoconfigure 其中包含了全场景的自动配置类
请添加图片描述

按需加载的自动配置

  • 每一个stater都会导入 spring-boot-starterspring-boot-starter是所有stater的stater
  • spring-boot-starter又导入了spring-boot-autoconfigure 其中包含了全场景的自动配置类,但并没有全部开启,只有导入了相关场景才开启对应的配置请添加图片描述

SPI机制

  • Java中的SPI(Service Provider Interface)是一种软件设计模式,用于在应用程序中动态地发现和加载组件。SPI的思想是,定义一个接口或抽象类,然后通过在classpath中定义实现该接口的类来实现对组件的动态发现和加载。
  • SPI的主要目的是解决在应用程序中使用可插拔组件的问题。例如,一个应用程序可能需要使用不同的日志框架或数据库连接池,但是这些组件的选择可能取决于运行时的条件。通过使用SPI,应用程序可以在运行时发现并加载适当的组件,而无需在代码中硬编码这些组件的实现类。
  • 在Java中,SPI的实现方式是通过在META-INF/services目录下创建一个以服务接口全限定名为名字的文件,文件中包含实现该服务接口的类的全限定名。当应用程序启动时,Java的SPI机制会自动扫描classpath中的这些文件,并根据文件中指定的类名来加载实现类。
  • 通过使用SPI,应用程序可以实现更灵活、可扩展的架构,同时也可以避免硬编码依赖关系和增加代码的可维护性。
  • SpringBoot的SPL是加载:META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

功能开关

  • 自动配置:全部都配置好,什么都不用管。 自动批量导入

    • 项目一启动,spi文件中指定的所有都加载。
  • @EnableXxxx:手动控制哪些功能的开启; 手动导入。

    • 开启xxx功能

    • 都是利用 @Import 把此功能要用的组件导入进去

Spring Boot 自定义配置

  • 使用@PropertySource进行自定义配置
    • 如果将所有的配置都集中到 application.properties 或 application.yml 中,那么这个配置文件会十分的臃肿且难以维护,因此可以将与 Spring Boot 无关的配置提取出来,写在一个单独的配置文件中,并在对应的 JavaBean 上使用 @PropertySource 注解指向该配置文件。
    • @PropertySource()可以同时支持多个配置文件用逗号隔开
  • 使用@ImportResource进行自定义配置
    • 可以使用注解@ImportResource 导入spring的配置文件,让配置文件生效。
    • 在主启动程序类上使用 @ImportResource 注解,将 Spring 配置文件 beans.xml 加载到项目中
  • 使用@Configuration进行自定义配置
    • @Configuration用在类上,表示告诉spring这个类是配置类===spring配置文件。
    • 配置类内部可以包含有一个或多个被 @Bean 注解的方法,这些方法会被 AnnotationConfigApplicationContext 或 AnnotationConfigWebApplicationContext 类扫描,构建 bean 定义,方法的返回值会以组件的形式添加到容器中,组件的 id 就是方法名。

Springboot:配置文件参数的获取

  • 非静态参数,直接使用@Value注解即可获取到参数
  • 静态参数,当工具类中的方法需要从配置文件读取参数时,需要将参数定义为静态,才可以在静态方法中获取到,这时候就不能只配置个@Value注解,还要在类上要加@Component注解

生命周期监听器

springboot启动流程

  • 在启动类的main方法中,通过调用SpringApplication的静态方法run()来完成整个项目的初始化和启动。
  • run方法里主要干了两件事:
    • 创建springbootApplication对象
      • 创建springbootApplication对象springboot容器初始化操作
      • 获取当前应用的启动类型:通过判断当前classpath是否加载servlet类,返回servlet web启动方式。
        • webApplicationType三种类型:
          • reactive:响应式启动(spring5新特性)
          • none:即不嵌入web容器启动(springboot放在外部服务器运行 )
          • servlet:基于web容器进行启动
      • 读取springboot下的META-INFO/spring.factories文件,获取对应的ApplicationContextInitializer(初始化器)装配到集合
      • 读取springboot下的META-INFO/spring.factories文件,获取对应的 ApplicationListener(初监听器)装配到集合
      • 初始化主类mainApplectionClass,定位main方法。
    • 并调用实例的run方法,run方法中重点做了以下操作
      • 获取监听器和参数配置;
      • 打印Banner信息;
      • 创建并初始化容器;
      • 监听器发送通知。

生命周期监听器(监听器-SpringApplicationRunListener ),用于监听应用的生命周期,启动过程如下:
在这里插入图片描述

监听器的启动过程

  • Listener先要从 META-INF/spring.factories 读到

  • SpringApplicationRunListener下的7个默认方法

    • 引导: 利用 BootstrapContext 引导整个项目启动
      • starting:应用开始,SpringApplication的run方法一调用,只要有了 BootstrapContext 就执行
      • environmentPrepared:环境准备好(把启动参数等绑定到环境变量中),但是ioc还没有创建;【调一次】
    • 启动:
      • contextPrepared:ioc容器创建并准备好,但是sources 主配置类没加载。并关闭引导上下文;组件都没创建 【调一次】
      • contextLoaded:ioc容器加载。主配置类加载进去了。但是ioc容器还没刷新(我们的bean没创建)。
      • started:ioc容器刷新了(所有bean造好了),但是 runner 没调用。
      • ready :ioc容器刷新了(所有bean造好了),所有 runner 调用完了。
    • failed:如果应用启动失败(starting之后,running之前),会执行的逻辑
  • 运行:以前步骤都正确执行,代表容器running(context.isRunning())。

自定义SpringApplicationRunListener来监听事件:

  • 编写SpringApplicationRunListener 实现类,用来监听spring的声明周期

  • 在 META-INF/spring.factories 中配置 org.springframework.boot.SpringApplicationRunListener=自己的Listener,还可以指定一个有参构造器,接受两个参数(SpringApplication application, String[] args)

  • springboot 在spring-boot.jar中配置了默认的 Listener,配置文件的写法为:

    org.springframework.boot.SpringApplicationRunListener=\
    com.psh.Listener.MyApplicationRunListener
    

事件驱动开发

应用启动过程生命周期事件感知(9大事件)**、**应用运行中事件感知(无数种)。

  • 事件发布:ApplicationEventPublisherAware注入:ApplicationEventMulticaster
  • 事件监听:组件 + @EventListener

事件驱动的开发的好处:

  • 如果在原本的登录功能上,需要新增新的服务,原本的开发方式需要修改登录接口
  • 而事件驱动的开发,不需要修改原本的代码,可以直接新增服务,监听登录事件,这样就做到了只新增,不修改(对扩展开放,对修改关闭)

请添加图片描述

场景如下:

  • 事件发布者发部事件,事件订阅者监听事件
  • 当事件发生时,监听这个事件的订阅者,可以自动执行某些逻辑
  • @Order(0)可以用来指定监听的顺序的,数组越小,优先级越高,默认的事件顺序是按照事件监听器名字的首字母排序的

请添加图片描述

自定义stater

自定义stater步骤

  • 创建自定义starter项目,引入spring-boot-starter基础依赖
  • 编写模块功能,引入模块所有需要的依赖。
  • 编写xxxAutoConfiguration自动配置类,帮其他项目导入这个模块需要的所有组件
  • 编写配置文件META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports指定启动需要加载的自动配置
  • 其他项目引入即可使用

自定义配置可以在配置文件中有提示

<!--导入配置处理器,配置文件自定义的properties配置都会有提示-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional>
</dependency>

自定义stater不需要启动类,抽取完业务代码后,编写一个自动配置类,导入需要的组件,因为springBoot默认只会导入主程序及其子包下的组件,所以需要手动导入

@Configuration
//导入容器中要用到的所有组件
@Import({CustomConfig.class, CustomController.class, CustomServiceImpl.class})
public class CustomAutoConfiguration {
}

然后再编写配置文件META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports指定启动需要加载的自动配置类

其他项目直接引用自定义的stater,并且再配置文件中写入对应的配置,就能有对应的功能

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

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

相关文章

excel、word、ppt 下载安装步骤整理

请按照我的步骤开始操作&#xff0c;注意以下截图红框标记处&#xff08;往往都是需要点击的地方&#xff09; 第一步&#xff1a;下载 首先进入office下载网址&#xff1a; otp.landian.vip 然后点击下载 拉到下方 下载站点&#xff08;这里根据自己的需要选择下载&#x…

汇编语言程序设计-7-高级汇编语言技术

7. 高级汇编语言技术 文章目录 7. 高级汇编语言技术7.0 导学7.1 子程序的另外一种写法-segment/ends-proc/endp7.2 程序的多文件组织7.3 汇编指令汇总7.4 汇编伪操作汇总7.5 汇编操作符汇总7.6 汇编过程7.7 宏汇编7.8 宏库7.9 条件汇编7.10 重复汇编7.11 80x86汇编7.12 汇编语言…

NAT地址转换+多出口智能选路,附加实验内容

本章主要讲&#xff1a;基于目标IP、双向地址的转换 注意&#xff1a;基于目标NAT进行转换 ---基于目标IP进行地址转换一般是应用在服务器端口映射&#xff1b; NAT的基础知识 1、服务器映射 服务器映射是基于目标端口进行转换&#xff0c;同时端口号也可以进行修改&…

方波的傅里叶变换及方波的MATLAB实现

一、傅里叶变换简介 傅里叶变换&#xff0c;表示能将满足一定条件的某个函数表示成三角函数&#xff08;正弦和/或余弦函数&#xff09;或者它们的积分的线性组合。傅里叶变换是一种线性的积分变换。它的理论依据是&#xff1a;任何连续周期信号都可以由一组适当的正弦曲线组合…

stm32h743 NetXduo 实现http server CubeIDE+CubeMX

在这边要设置mpu的大小,要用到http server,mpu得设置的大一些 我是这么设置的,做一个参考 同样,在FLASH.ld里面也要对应修改,SECTIONS里增加.tcp_sec和 .nx_data两个区,我们用ram_d2区域去做网络,这个就是对应每个数据在d2区域的起点。 在CubeMX里,需要用到filex、dhc…

无损音乐播放器推荐:Audirvana for Mac 中文激活版

udirvana 是一款高品质的音乐播放软件&#xff0c;专为Mac操作系统设计。它被设计来提供音频播放的最高标准&#xff0c;支持多种音频格式&#xff0c;包括高达32位/192kHz的高分辨率音频。Audirvana Plus 是其高级版本&#xff0c;提供了更多的功能和优化&#xff0c;例如音频…

Qt Mqtt客户端 + Emqx

环境 Qt 5.14.2 qtmqtt mqttx 功能 QT Mqtt客户端 qtmqtt 下载 qtmqtt (注意下载与QT版本相符的库)并使用QT 编译 编译完成后需要的文件: emqx 1.虚拟机中安装emqx,并启动 curl -s https://assets.emqx.com/scripts/install-emqx-deb.sh | sudo bash sudo apt-get inst…

前端Vue组件化实践:打造仿京东天猫商品属性选择器组件

在前端开发领域&#xff0c;随着业务需求的日益复杂和技术的不断进步&#xff0c;传统的整体式应用开发模式已逐渐显得捉襟见肘。面对日益庞大的系统&#xff0c;每次微小的功能修改或增加都可能导致整个逻辑结构的重构&#xff0c;形成牵一发而动全身的困境。为了解决这一问题…

树莓派PICO使用INA226测量电流和总线电压(3)

上一篇文章我们讲了如何测试电流&#xff0c;但是INA226有一个非常典型的问题&#xff0c;那就是误差比较大&#xff0c;因为采样电阻非常小&#xff0c;我的开发板用的是100mΩ的采样电阻&#xff0c;在设定中我也用的是这个采样电阻值&#xff0c;但事实上&#xff0c;测试得…

免费开源工具—— Clarity Al:一键图像放大/增强,Magnific平替!

今天给大家推荐一款图像增强工具——Clarity AI &#xff0c;免费且开源&#xff0c;快来看看吧&#xff01; 1、效果展示 MagnificAl是一款基于人工智能技术的图像处理工具,主要功能包括图像放大、像素级AI重绘、灵活的设置调整以及多种优化场景。它能够支持最高放大至16倍,甚…

算法力扣刷题记录 四十五【110.平衡二叉树】

前言 二叉树篇继续 记录 四十五【110.平衡二叉树】 一、题目阅读 给定一个二叉树&#xff0c;判断它是否是 平衡二叉树。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;true示例 2&#xff1a; 输入&#xff1a;root [1,2,2,3,3…

电容充放电时间计算

电容充电时间的结论&#xff1a;t充电 R * C 时&#xff0c;Ut2*VCC/3&#xff0c;这是一个不能让我释怀的结论。 1、电池充电 U0表示电容C在充电0时刻的电压值; Ut表示电容C在充电t时刻的电压值; U1表示电容C在充电∝时刻的电压值&#xff0c;就是电源电压; Q C * U ---…

【C/C++积累技巧】实现 连续播放文件图片+逐帧文本显示, 同时 可以按任意键退出(基于easyx小游戏编程)

技巧一、使用 IMAGE数组循环&#xff1a;实现【连续播放图片】 &#xff08;1&#xff09;一张图片如何放映在 图形化窗口上&#xff1a;借用两个函数 #include<graphics.h> // 函数的头文件IMAGE imgMy; // 图形变量 loadimage(&imgMy, "写入你想显示的图片路…

Java高频面试基础知识点整理27

干货分享&#xff0c;感谢您的阅读&#xff01;背景​​​​​​高频面试题基本总结回顾&#xff08;含笔试高频算法整理&#xff09; 最全文章见&#xff1a;Java高频面试基础知识点整理 &#xff08;一&#xff09;Java基础高频知识考点 针对人员&#xff1a; 1.全部人员都…

vs2019 QT无法打开源文件QModbusTcpClient

vs2019无法打开源文件QModbusTcpClient 如果配置的msvc2019,则查找到Include目录 然后包含&#xff1a; #include <QtSerialBus/qmodbustcpclient.h>

STL 提供的容器可以有多快?(下)「榨干最后一滴」

以下内容为本人的烂笔头&#xff0c;如需要转载&#xff0c;请声明原文链接 微信公众号「ENG八戒」https://mp.weixin.qq.com/s/QWgA97TDMGBnwR4hKA7BwA 查表的消耗 某些场景下需要用到大量的 (string, X) 键值对来存储数据&#xff0c;标准库提供了关联容器 std::map 来解决键…

Python酷库之旅-第三方库Pandas(021)

目录 一、用法精讲 52、pandas.from_dummies函数 52-1、语法 52-2、参数 52-3、功能 52-4、返回值 52-5、说明 52-6、用法 52-6-1、数据准备 52-6-2、代码示例 52-6-3、结果输出 53、pandas.factorize函数 53-1、语法 53-2、参数 53-3、功能 53-4、返回值 53-…

经典卷积网络

放假回家了&#xff0c;感觉快坚持不下去了&#xff0c;目前还没有找到关于无监督学习实现分类的课程&#xff0c;普通数据当然肯定不会给你实现分类的啊 给些建议吧。 LeNet 通过共享卷积核&#xff0c;减少网络参数。 一般只统计卷积计算层和全连接计算层&#xff0c;其余操…

【redis操作语句】

1.数据库操作 redis默认有16个数据库&#xff0c;编号为0~15&#xff0c;且默认访问0号数据库 获取当前键值对数量:先set创建一个键值对,再用dbsize获取&#xff0c;flushdb清空再获取。 127.0.0.1:6379> set k1 v1 OK 127.0.0.1:6379> dbsize (integer) 1 127.0.0.1:…

安卓onNewIntent 什么时候执行

一.详细介绍 onNewIntent 方法 onNewIntent 是 Android 中 Activity 生命周期的一部分。它在特定情况下被调用&#xff0c;主要用于处理新的 Intent&#xff0c;而不是创建新的 Activity 实例。详细介绍如下&#xff1a; 使用场景 singleTop 启动模式&#xff1a; 如果一个 Ac…