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容器

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

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

相关文章

蓝桥杯-灌溉

参考了大佬的解题思路&#xff0c;先遍历一次花园&#xff0c;找到所有的水源坐标&#xff0c;把它们存入 “水源坐标清单” 数组内&#xff0c;再读取数组里的水源坐标进行扩散。 #include <iostream> using namespace std; int main() {int n,m,t,r,c,k,ans0,list_i0;…

(每日持续更新)jdk api之OutputStreamWriter基础、应用、实战

博主18年的互联网软件开发经验&#xff0c;从一名程序员小白逐步成为了一名架构师&#xff0c;我想通过平台将经验分享给大家&#xff0c;因此博主每天会在各个大牛网站点赞量超高的博客等寻找该技术栈的资料结合自己的经验&#xff0c;晚上进行用心精简、整理、总结、定稿&…

c++ for 循环语句

循环语句 在C中&#xff0c;有几种循环语句可用于重复执行一段代码&#xff0c;直到满足指定条件为止&#xff0c;主要有 for 循环、while 循环、do-while 循环三种循环语句。三者区别&#xff1a; 循环类型特点for 循环1. 适用于已知循环次数的情况&#xff0c;循环次数事先…

推荐系统经典模型YouTubeDNN代码

文章目录 前言数据预处理部分模型训练预测部分总结与问答 前言 上一篇讲到过YouTubeDNN论文部分内容&#xff0c;但是没有代码部分。最近网上教学视频里看到一段关于YouTubeDNN召回算法的代码&#xff0c;现在我分享一下给大家参考看一下&#xff0c;并附上一些我对代码的理解…

一张图读懂人工智能

一、生成人工智能的概念和应用&#xff0c;以及如何使用大型语言模型进行聊天和创造原创内容。这项技术将会对人类和企业产生深远影响。 计算机获得学习、思考和交流的能力&#xff0c;被称为生成人工智能。生成人工智能可以立即获得人类所有知识的总和&#xff0c;并回答任何…

综合实战(volume and Compose)

"让我&#xff0c;重获新生~" MySQL 灾难恢复 熟练掌握挂载卷的使用&#xff0c;将Mysql的业务数据存储在 外部。 实战思想: 使用 MySQL 5.7 的镜像创建容器并创建一个普通数据卷 "mysql-data"用来保存容器中产生的数据。我们需要容器连接到Mysql服务&a…

TeXiFy IDEA 编译后文献引用为 “[?]“

文章目录 1. 问题描述2. 原因分析3. 解决方案3.1 添加自动化脚本3.2 附录——配置一览表 1. 问题描述 在 IDEA 中使用 TeXiFy IDEA 编译后的文章文献引用是 [?] 2. 原因分析 根据网上教程所生成的目录结构如下&#xff1a; 报错日志&#xff1a; 根据 /out 目录结构&#x…

【vmware安装群晖】

vmware安装群晖 vmware安装群辉&#xff1a; vmware版本&#xff1a;17pro 下载链接&#xff0c; https://customerconnect.vmware.com/cn/downloads/details?downloadGroupWKST-1751-WIN&productId1376&rPId116859 激活码可自行搜索 教程&#xff1a; https://b…

C++重新入门-string容器

目录 1.包含头文件 2.创建字符串 3.获取字符串长度 4.字符串拼接 5.字符串比较 相等性比较 大小比较 使用比较函数 6.访问字符串 7.查找子串 8.字符串修改 替换子串 插入字符或子串 删除字符或子串 9.提取子串 10.总结 当谈到C中的字符串时&#xff0c;std::str…

135.乐理基础-半音是小二度吗?全音是大二度吗?三全音

内存参考于&#xff1a;三分钟音乐社 上一个内容&#xff1a;134.乐理基础-音程名字的简写-CSDN博客 上一个内容里练习的答案&#xff1a; 半音可以与小二度划等号吗&#xff1f;全音可以和大二度划等号吗&#xff1f; 严格来说它们是不能划等号的&#xff0c;半音与全音是侧…

基于springboot实现的健康监控管理系统

一、系统架构 前端&#xff1a;html | bootstrap | jquery | css 后端&#xff1a;springboot | thymeleaf | mybatis 环境&#xff1a;jdk1.8 | mysql | maven 二、代码及数据库 三、功能介绍 01. 体检测评 02. 运动处方 03. 运动处方明细 04. 运动处方-打卡…

基于transform的scale属性,动态缩放整个页面,实现数据可视化大屏自适应,保持比例不变形,满足不同分辨率的需求

文章目录 一、需求背景&#xff1a;二、需求分析&#xff1a;三、选择方案&#xff1a;四、实现代码&#xff1a;五、效果预览&#xff1a;六、封装组件&#xff1a; 一、需求背景&#xff1a; 数据可视化大屏是一种将数据、信息和可视化效果集中展示在一块或多块大屏幕上的技…

PyTorch基础(19)-- torch.take_along_dim()方法

一、前言 在深挖ML4CO的代码过程中&#xff0c;遇到了torch.take_along_dim()这个方法&#xff0c;影响到我后续的代码阅读&#xff1b;加之在上网搜索资料的过程中&#xff0c;网络上对此函数的介绍文章少之又少&#xff0c;即使有&#xff0c;也是对torch官网文档中的解释进…

价格腰斩:腾讯云和阿里云服务器优惠价格对比

2024年阿里云服务器和腾讯云服务器价格战已经打响&#xff0c;阿里云服务器优惠61元一年起&#xff0c;腾讯云服务器62元一年&#xff0c;2核2G3M、2核4G、4核8G、8核16G、16核32G、16核64G等配置价格对比&#xff0c;阿腾云atengyun.com整理阿里云和腾讯云服务器详细配置价格表…

jvm面试题目补充

jdk&jre Java程序设计语言、Java虚拟机、Java API类库这三部分统称为JDK&#xff08;Java Development Kit&#xff09;。 把Java API类库中的Java SE API子集 [1] 和Java虚拟机这两部分统称为JRE&#xff08;Java Runtime Environment&#xff09;&#xff0c;JRE是支持…

CUDA C:查看GPU设备信息

相关阅读 CUDA Chttps://blog.csdn.net/weixin_45791458/category_12530616.html?spm1001.2014.3001.5482 了解自己设备的性能是很有必要的&#xff0c;为此CUDA 运行时(runtime)API给用户也提供了一些查询设备信息的函数&#xff0c;下面的函数用于查看GPU设备的一切信息。 …

MyBatis 学习(二)之 第一个 MyBatis 案例

目录 1 配置 MyBatis 方式 1.1 XML 配置文件 1.2 Java 注解配置 1.3. Java API 配置 2 在 MySQL 中创建一张表 3 创建一个基于 Maven 的 JavaWeb 工程 4 编写 User 实体类 5 创建 Mybatis 全局配置文件 6 编写一个 DAO 或 Mapper 接口 7 编写 SQL 映射配置文件&#…

找不到mfc140.dll怎么办?教你五种mfc140.dll丢失的解决方法

当计算机系统中mfc140.dll文件丢失时&#xff0c;可能会引发一系列运行问题&#xff0c;影响到系统的正常功能及应用程序的稳定执行。具体来说&#xff0c;由于mfc140.dll是Microsoft Visual C Redistributable Package的重要组成部分&#xff0c;它的缺失会导致依赖于该动态链…

如何用好应用权限,保护隐私数据?银河麒麟桌面操作系统V10 SP1 2303 update2新功能解析

为您介绍银河麒麟桌面操作系统V10 SP1 2303 update2隐私设置和权限管理功能&#xff0c;为您的个人数据安全保驾护航。 说到个人数据隐私&#xff0c;在科技重塑生活本质的数字世界&#xff0c;个人信息遭受持续威胁。2018年&#xff0c;某国际知名社交平台因安全系统漏洞而遭…

深入解析Mybatis-Plus框架:简化Java持久层开发(六)

&#x1f340; 前言 博客地址&#xff1a; CSDN&#xff1a;https://blog.csdn.net/powerbiubiu &#x1f44b; 简介 上一章介绍了新增的操作&#xff0c;后续删除&#xff0c;更新&#xff0c;查询的操作相对新增要复杂一些&#xff0c;因为有些方法的使用涉及到了条件&…