当前位置: 首页 > news >正文

SpringBoot底层原理

SpringBoot底层原理

一 配置优先级

1.配置方式

Springboot中支持三种配置方式,分别为:

  • application.properties
  • application.yml
  • application.yaml

2.配置优先级

当存在多份配置文件时,配置文件会按照它们的优先级生效。

优先级从高到底分别为:application.peoperties>application.yml>application.yaml

目前 application.yml 是最主流的方式

3.其他配置方式

Springboot除了以上常见的三种配置方式之外,还支持Java系统属性配置和命令行参数配置。

1.Java系统属性配置示例

# 在 java 命令后使用 —D 命令,然后书写需要配置的属性即可
# 示例中配置了项目的运行端口为8081,即server.port=8081
java -Dserver.port=8081 -jar [packageName].jar

2.命令行参数配置示例

# 在jar包名称之后,使用双横杠(--),后面紧跟配置的参数即可
java -jar [packageName].jar --server.port=8082

二 Bean管理

1.获取bean对象

默认情况下,Springboot项目在启动时会自动创建bean,并且将这些bean都存放在IOC容器中。

如果想手动获取这些bean,则可以通过以下几种示例。

首先需要注入ApplicationContext对象。

Spring框架中,ApplicationContext是一个接口,代表了Spring容器,它负责管理Spring应用程序中所有的bean,同时提供了一些方法来获取Bean,注册Bean,是整个Spring应用的核心。

默认情况下,一个Bean的名称是它的类名名称,然后将首字母小写。

例如 DeptController,它在IOC容器中的默认名称为 deptController

@Autowired
private ApplicationContext applicationContext;
@Test
void test1(){//1.根据bean的名称来获取bean对象EmpServiceImpl empServiceImpl1= (EmpServiceImpl) applicationContext.getBean("empServiceImpl");System.out.println(empServiceImpl1);//2.根据bean的类型来获取bean对象EmpServiceImpl empServiceImpl2= applicationContext.getBean(EmpServiceImpl.class);System.out.println(empServiceImpl2);//3.根据bean的类型和名称来获取bean对象// 以下方法和示例,在bean的默认名称被修改且有多个同类型的bean时,尤为有用。EmpServiceImpl empServiceImpl3= applicationContext.getBean("empServiceImpl",EmpServiceImpl.class);System.out.println(empServiceImpl3);
}

运行以上示例,可以看出,bean在IOC容器中,默认是单例存在的。
在这里插入图片描述如果想要实现每次使用时都是一个新的bean,则需要通过bean的作用域来进行配置。

2.bean的作用域

在Spring中,bean支持五种作用域,后三种在web环境下才能生效。

在这里插入图片描述

默认情况下,Bean对象在项目启动时就会默认实例化。如果不希望在项目启动时就初始化,可以使用@Lazy注解,让Bean对象延迟初始化,直到第一次使用该Bean时才会进行初始化。

@Service
@Lazy
public class EmpServiceImpl extends ServiceImpl<EmpMapper, Emp> implements EmpService{//code...
}

设置Bean的作用域,则需要通过@Scope注解来实现。

以下示例中,我们将Bean的作用域设置为 prototype,即每次使用该Bean时都会创建新对象。

@Service
@Scope("prototype")
public class EmpServiceImpl extends ServiceImpl<EmpMapper, Emp> implements EmpService{//code...
}

现在再次运行前边获取Bean对象的代码示例,可以发现,三次获取到的Bean对象,已经不是同一个。
在这里插入图片描述

3.声明第三方bean

如果要申明的Bean来自第三方,是无法通过@Component及衍生注解来申明的,这个时候就需要使用@Bean注解。

以 SAXReader 类为例,创建一个返回值为SAXReader对象的方法,方法名称就是以后被ICO管理的Bean对象名称。

//将方法的返回值交给IOC容器管理,称为IOC容器的Bean对象
@Bean
public SAXReader saxReader(){return new SAXReader();
}

在以后需要用到 SAXReader 对象的时候,直接注入即可,不用去实例化。

@Autowired
private SAXReader saxReader;
@Test
void test2() throws DocumentException {Document document = saxReader.read("xxx");
}

注意:一般情况下,我们通常会将所有需要申明的第三方bean对象统一放在一个配置类中,这样更加方便维护。

@Configuration
public class BeanAutoConfig {// 可以通过@Bean注解的 name /value 属性来定义bean的名称// 默认情况下,bean的名称就是方法名@Beanpublic RestTemplate restTemplate(){return new RestTemplate();}}

在声明第三方bean对象时,如果需要进行依赖注入,则只需要指定方法形参即可。Spring会根据类型进行自动装配。

// EmpServiceImpl对象是要注入的bean对象
@Bean
public RestTemplate restTemplate(EmpServiceImpl empServiceImpl){empServiceImpl.[xxx];return new RestTemplate();
}

三 Springboot原理

1.Springboot起步依赖

Springboot整合了以前web开发需要用的一些依赖项,目前使用Springboot开发web项目,只需要引入 spring-boot-start-web 依赖即可。
在这里插入图片描述
归根结底,SPringboot起步依赖的原理就是maven的依赖传递

2.自动配置

当Springboot项目启动后,Springboot中的一些配置类,bean对象就会自动存入到IOC容器中,不需要我们手动去申明。从而简化了开发,省去了繁琐的配置。

3.管理第三方包中的Bean

1.配置实现方式1:@ComponentScan 组件扫描

在启动类上使用 @ComponentScan注解,重新配置包扫描路径。@ComponentScanbasePackages参数支持数据格式,当有多个第三方包时,可使用数组形式申明。

@ComponentScan(basePackages = "xxx1")

@ComponentScan(basePackages = {"xxx1","xxx2"
})

注意:使用@ComponentScan申明时,当前Springboot项目中的包路径也必须包含在内,否则当前项目中的bean将会被无法识别。

缺点:当项目较大时,引入大量的第三方依赖,此时启动类将会显得臃肿。

2.配置实现方式2:@Import 组件导入

使用@Import导入的类会被Spring加载到容器中。可以导入普通类,配置类,以及 ImportSelector 接口的实现类,支持数组。

@Import({xx1.class,xx2.class})

实现ImportSelector 接口,这里最核心的就是 selectImports方法,它返回了需要创建Bean对象的全部类。

public class MyImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {//此处的数组内容为需要导入的Bean对象的全类名,有多少写多少return new String[]{"springboot.demo.GoodStudent"};}
}

然后在启动类上使用@Import注解即可。

@Import({MyImportSelector.class})

单纯使用 @Import接口声明第三方Bean,缺点很明显。

3.配置实现方式3:第三方依赖提供注解

实际项目中,具体第三方依赖需要导入哪些Bean,只有第三方依赖自己知道。所以可以由第三方依赖提供注解,然后在项目中引入即可。

此类型注解一般均由 Enable 开头,原理是在自定义注解中封装 @Import 注解。

示例:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import({MybatisPlusConfig.class,CorsConfig.class,SpringWebConfig.class,BeanAutoConfig.class,RedisConfig.class
})
public @interface EnableShawnConfig {}

在第三方依赖包中定义一个EnableShawnConfig注解,然后使用 @Import将需要配置的Bean对象都引入进来。最后再在项目中使用该注解即可。

@EnableShawnConfig
@SpringBootApplication
public class ShawnServerSystemApplication {public static void main(String[] args) {SpringApplication.run(ShawnServerSystemApplication.class, args);}
}

4.自动配置原理分析

Springboot核心注解:@SpringBootApplication

@SpringBootApplication下的重要注解:

  • @SpringBootConfiguration:申明当前注解也是一个配置类,因为@SpringBootConfiguration中也申明了@Configuration注解。所以可以直接在启动类中申明第三方的bean对象。
  • @EnableAutoConfiguration:Springboot自动配置的核心注解,它声明了@Import(AutoConfigurationImportSelector.class)AutoConfigurationImportSelectorImportSelector接口的实现类,实现了 selectImports 方法selectImports 方法返回了需要创建Bean对象的全部信息。
  • @ComponentScan:组件扫描,默认扫描当前引导类及其所在的子包。

自动配置最核心的注解就是@EnableAutoConfiguration,由源码可知,selectImports 方法会读取一个固定目录下后缀名为.imports的文件。

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {List<String> configurations = ImportCandidates.load(AutoConfiguration.class, getBeanClassLoader()).getCandidates();Assert.notEmpty(configurations,"No auto configuration classes found in "+ "META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you "+ "are using a custom packaging, make sure that file is correct.");return configurations;
}

springboot3.x中,META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中,配置了需要创建Bean对象的全类名

在Springboot2.x中,是通过两个关键文件来读取配置好的全类名的。
在这里插入图片描述
spring.factories 是早起Springboot版本中自动配置的文件,在后续版本中已经逐渐不再使用。

5.@Conditinal注解

@Conditinal注解的作用:按照一定的条件判断,在满足条件后才会注册对应的Bean对象到IOC容器中

它可以作用在方法上。

@Conditinal本身是一个父级注解,它衍生除了很多子级注解

  • @ConditionalOnClass:判断环境中是否存在字节码文件,有则注册bean对象到IOC容器
  • @ConditionalOnMissingBean:判断环境中有没有对应的Bean(根据类型和名称),没有则注册Bean对象到IOC容器
  • @ConditionalOnProperty:判断配置文件中是否有对应属性和值,有则注册bean对象到IOC容器

相关文章:

SpringBoot底层原理

SpringBoot底层原理 一 配置优先级 1.配置方式 Springboot中支持三种配置方式&#xff0c;分别为&#xff1a; application.propertiesapplication.ymlapplication.yaml 2.配置优先级 当存在多份配置文件时&#xff0c;配置文件会按照它们的优先级生效。 优先级从高到底…...

【golang】25、图片操作

用 “github.com/fogleman/gg” 可以画线, 框 用 “github.com/disintegration/imaging” 可以变换颜色 一、渲染 1.1 框和字 import "github.com/fogleman/gg"func DrawRectangles(inPath string, cRects []ColorTextRect, fnImgNameChange FnImgNameChange) (st…...

kswapd0挖矿病毒攻击记录

文章目录 一、起因与病毒分析1、起因2、阿里云告警2.1 恶意脚本代码执行12.2 恶意脚本代码执行22.3恶意脚本代码执行32.4 恶意脚本代码执行4 3、病毒简单分析3.1 病毒的初始化3.2 病毒本体执行 4、总结 二、ubuntu自救指南1、病毒清理2、如何防御 一、起因与病毒分析 1、起因 …...

如何使用 takeUntil RxJS 操作符来声明性地管理订阅

简介 Angular 处理取消订阅可观察对象的操作&#xff0c;比如从 HTTP 服务返回的可观察对象或者使用 async 管道时。然而&#xff0c;对于其他情况&#xff0c;管理所有订阅并确保取消长期存在的订阅可能会变得困难。而且&#xff0c;取消大部分订阅的策略也会带来自己的问题。…...

在Centos中用Docker部署oracle-12c

一、介绍 Oracle 12c是Oracle 11g的后续版本。12c代表云计算&#xff08;Cloud Computing&#xff09;&#xff0c;这是Oracle在该版本中强调的一个关键概念。它具有多租户架构、数据库内存、安全增强、大数据管理和自动化管理等功能。它被广泛应用于企业级应用程序和大型数据…...

JS进阶——高级技巧

版权声明 本文章来源于B站上的某马课程&#xff0c;由本人整理&#xff0c;仅供学习交流使用。如涉及侵权问题&#xff0c;请立即与本人联系&#xff0c;本人将积极配合删除相关内容。感谢理解和支持&#xff0c;本人致力于维护原创作品的权益&#xff0c;共同营造一个尊重知识…...

TG-ADMIN 权限管理系统

项目简介 该项目是一款基于 SpringBoot + Vue2 + Jwt + ElementUi的 RBAC模型管理系统。 主要以自定义拦截器和jwt结合进行权限验证 通过自定义指令实现按钮级别权限,使用经典的RBAC模型 什么是RBAC? 1、RBAC模型概述 RBAC模型(Role-Based Access Control:基于角色的…...

十五届蓝桥杯第三期模拟赛题单(C++、java、Python)

备战2024年蓝桥杯 省赛第三期模拟赛题单 备战Python大学A组 第一题 【问题描述】 请问 2023 有多少个约数&#xff1f;即有多少个正整数&#xff0c;使得 2023 是这个正整数的整数倍。 【问题描述】 这是一道结果填空的题&#xff0c;你只需要算出结果后提交即可。本题的结果…...

嵌入式驱动学习第一周——git的使用

前言 本文主要介绍git的使用&#xff0c;包括介绍git&#xff0c;gitee&#xff0c;以及使用gitee创建仓库并托管代码 嵌入式驱动学习专栏将详细记录博主学习驱动的详细过程&#xff0c;未来预计四个月将高强度更新本专栏&#xff0c;喜欢的可以关注本博主并订阅本专栏&#xf…...

界面控件DevExpress .NET MAUI v23.2新版亮点 - 拥有全新的彩色主题

DevExpress拥有.NET开发需要的所有平台控件&#xff0c;包含600多个UI控件、报表平台、DevExpress Dashboard eXpressApp 框架、适用于 Visual Studio的CodeRush等一系列辅助工具。屡获大奖的软件开发平台DevExpress 今年第一个重要版本v23.1正式发布&#xff0c;该版本拥有众多…...

大语言模型LLM Pro+中Pro+(Prompting)的意义

—— Pro &#xff0c;即Prompting&#xff0c;构造提示 1.LLM Pro中Pro&#xff08;Prompting&#xff09;的意义 Prompting不仅是大语言模型交互和调用的一种高效手段&#xff0c;而且已成为推动模型泛化能力和应用灵活性的关键技术路径&#xff0c;它不仅极大地拓展了模型功…...

React 中,children 属性

在 React 中&#xff0c;children 属性是一个特殊的属性&#xff0c;它允许你将组件作为其他组件的子元素传递。这意味着你可以在组件内部嵌套任何类型的子组件或元素&#xff0c;并且在父组件中通过 props.children 访问它们。这为组件的复用和组合提供了极大的灵活性。 以下…...

多行业万能预约门店小程序源码系统 支持多门店预约小程序 带完整的安装代码包以及搭建教程

随着消费者对于服务体验要求的不断提升&#xff0c;门店预约系统成为了许多行业提升服务质量、提高运营效率的重要工具。然而&#xff0c;市面上的预约系统往往功能单一&#xff0c;无法满足多行业、多场景的个性化需求。下面&#xff0c;小编集合了多年的行业经验和技术积累&a…...

Node.js 中 fs 模块文件操作的应用教程

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境&#xff0c;它可以让 JavaScript 代码在服务器端运行。在 Node.js 中&#xff0c;fs 模块是用来处理文件系统操作的模块。通过 fs 模块&#xff0c;我们可以进行文件的读取、写入、删除等操作。本教程将介绍如何在 No…...

一些常用到的git命令

git stash -a //缓存所有文件 git checkout -b dev origin/dev //切换到dev分支上,接着跟远程的origin地址上的dev分支关联起来 //推送本地分支到远程仓库 git push origin localbranchname:remotebrancname git revert onefile //https://www.freecodecamp.org/news/git-re…...

spring boot3解决跨域的几种方式

⛰️个人主页: 蒾酒 &#x1f525;系列专栏&#xff1a;《spring boot实战》 &#x1f30a;山高路远&#xff0c;行路漫漫&#xff0c;终有归途。 目录 1.前言 2.何为跨域 3.跨域问题出现特征 4.方式一&#xff1a;使用 CrossOrigin 注解 5.方式二&#xff1a;自定义…...

【Spring】19 @Autowired注解使用详解

文章目录 构造函数注入Setter方法注入字段注入数组和集合注入特殊情况处理特殊接口类型的注入异常处理结语 Spring 框架的 Autowired 注解是实现依赖注入的一种强大而灵活的方式。在本文中&#xff0c;我们将介绍 Autowired 注解的多种用法&#xff0c;包括构造函数、setter方法…...

Educational Codeforces Round 132 (Rated for Div. 2) E. XOR Tree(启发式合并+贪心)

题目 n(n<2e5)个点的树&#xff0c;点i权值ai&#xff08;1<ai<2^30&#xff09; 修改最少的点的权值&#xff0c;使得树上不存在异或和为0的简单路径&#xff0c;输出最少的点数 权值可以被修改成任意正整数&#xff08;可以是无限大&#xff09; 思路来源 官方…...

JavaScript 基本数据类型的详解

JavaScript的基本数据类型 以下都是JS内置的几种类型 数据类型描述number数字&#xff0c;不区分整数和小数string字符串类型booleantrue 真, false 假undefined表示未定义的值null只有唯一的值 null&#xff0c;表示空值 number 数字类型 JavaScript 中不区分整数和浮点数&…...

DDR5内存相比DDR4内存的优势和区别?选择哪一个服务器内存配置能避免丢包和延迟高?

根据幻兽帕鲁服务器的实际案例分析&#xff0c;选择合适的DDR4与DDR5内存大小以避免丢包和延迟高&#xff0c;需要考虑以下几个方面&#xff1a; 性能与延迟&#xff1a;DDR5内存相比DDR4在传输速率、带宽、工作电压等方面都有显著提升&#xff0c;但同时也伴随着更高的延迟。D…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

人机融合智能 | “人智交互”跨学科新领域

本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...