day14-SpringBoot 原理篇

一、配置优先级

SpringBoot 中支持三种格式的配置文件:
在这里插入图片描述

注意事项

  • 虽然 springboot 支持多种格式配置文件,但是在项目开发时,推荐统一使用一种格式的配置 (yml 是主流)。

配置文件优先级排名(从高到低):

  1. properties 配置文件
  2. yml 配置文件
  3. yaml 配置文件

SpringBoot 除了支持配置文件属性配置,还支持 Java 系统属性命令行参数 的方式进行属性配置。
在这里插入图片描述

优先级: 命令行参数 > 系统属性参数 > properties 参数 > yml 参数 > yaml 参数

项目已经打包上线了,这个时候我们又如何来设置Java系统属性和命令行参数呢?
在这里插入图片描述

注意事项

  • Springboot 项目进行打包时,需要引入插件 spring-boot-maven-plugin (基于官网骨架创建项目,会自动添加该插件)
    <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId>                </plugin></plugins></build>

二、Bean 管理

1 获取 Bean

默认情况下,Spring 项目启动时,会把 bean 都创建好放在 IOC 容器中,如果想要主动获取这些 bean,可以通过如下方式:

  • 根据 name 获取 bean:
    Object getBean(String name)
  • 根据类型获取 bean:
    <T> T getBean(Class<T> requiredType)
  • 根据 name获取 bean(带类型转换):
    <T> T getBean(String name, Class<T> requiredType)

上述所说的 【Spring 项目启动时,会把其中的 bean 都创建好】还会受到作用域及延迟初始化影响,这里主要针对于 默认的单例非延迟加载的 bean 而言。

@SpringBootTest
class SpringbootWebConfig2ApplicationTests {@Autowiredprivate ApplicationContext applicationContext; //IOC容器对象//获取bean对象@Testpublic void testGetBean(){//根据bean的名称获取DeptController bean1 = (DeptController) applicationContext.getBean("deptController");System.out.println(bean1);//根据bean的类型获取DeptController bean2 = applicationContext.getBean(DeptController.class);System.out.println(bean2);//根据bean的名称 及 类型获取DeptController bean3 = applicationContext.getBean("deptController", DeptController.class);System.out.println(bean3);}
}

2 Bean 作用域

Spring 支持五种作用域
在这里插入图片描述

可以通过 @Scope 注解来进行配置作用域:

//@Lazy
@Scope("prototype")
@RestController
@RequestMapping("/depts")
public class DeptController {
}

注意事项:

  • 默认 singleton 的 bean,在容器启动时被创建,可以使用 @Lazy 注解来延迟初始化(延迟到第一次使用时)。
  • prototype 的 bean,每一次使用该 bean 的时候都会创建一个新的实例。
  • 实际开发当中,绝大部分的 Bean 是单例的,也就是说绝大部分 Bean 不需要配置 scope 属性。
@SpringBootTest
class SpringbootWebConfig2ApplicationTests {@Autowiredprivate ApplicationContext applicationContext; //IOC容器对象//bean的作用域@Testpublic void testScope(){for (int i = 0; i < 10; i++) {DeptController deptController = applicationContext.getBean(DeptController.class);System.out.println(deptController);}}
}

3 第三方 Bean

如果要管理的 bean 对象来自于第三方(不是自定义的),是无法用 @Component 及衍生注解声明 bean 的,就需要用到 @Bean 注解。

解决方案1:在启动类上添加 @Bean 标识的方法(不建议,项目中要保证启动类的纯粹性)

@SpringBootApplication
public class SpringbootWebConfig2Application {public static void main(String[] args) {SpringApplication.run(SpringbootWebConfig2Application.class, args);}//声明第三方bean@Bean //将当前方法的返回值对象交给IOC容器管理, 成为IOC容器beanpublic SAXReader saxReader(){return new SAXReader();}
}
@SpringBootTest
class SpringbootWebConfig2ApplicationTests {@Autowiredprivate ApplicationContext applicationContext; //IOC容器对象@Autowiredprivate SAXReader saxReader;//第三方bean的管理@Testpublic void testThirdBean() throws Exception {//SAXReader saxReader = new SAXReader();Document document = saxReader.read(this.getClass().getClassLoader().getResource("1.xml"));Element rootElement = document.getRootElement();String name = rootElement.element("name").getText();String age = rootElement.element("age").getText();System.out.println(name + " : " + age);}
}

解决方案2:在配置类中定义 @Bean 标识的方法

  • 若要管理的第三方 bean 对象,建议对这些 bean 进行集中分类配置,可以通过 @Configuration 注解声明一个配置类。
@Configuration //配置类
public class CommonConfig {//声明第三方bean@Bean //将当前方法的返回值对象交给IOC容器管理, 成为IOC容器bean//通过@Bean注解的name/value属性指定bean名称, 如果未指定, 默认是方法名public SAXReader reader(DeptService deptService){System.out.println(deptService);return new SAXReader();}}

注意事项:

  • 通过 @Bean 注解的 name 或 value 属性可以声明 bean 的名称,如果不指定,默认 bean 的名称就是方法名。
  • 如果第三方 bean 需要依赖其它 bean 对象,直接在 bean 定义方法中设置形参即可,容器会根据类型自动装配。

@Component 及衍生注解 与 @Bean 注解使用场景?

  • 项目中自定义的,使用 @Component 及其衍生注解
  • 项目中引入第三方的,使用 @Bean 注解

三、SpringBoot 原理

在这里插入图片描述
通过 SpringBoot 来简化 Spring 框架的开发(是简化不是替代)。我们直接基于 SpringBoot 来构建 Java 项目,会让我们的项目开发更加简单,更加快捷。

在这里插入图片描述

  • 通过 SpringBoot 所提供的起步依赖,就可以大大的简化 pom 文件当中依赖的配置,从而解决了 Spring 框架当中依赖配置繁琐的问题。
  • 通过自动配置的功能就可以大大的简化框架在使用时 bean 的声明以及 bean 的配置。我们只需要引入程序开发时所需要的起步依赖,项目开发时所用到常见的配置都已经有了,我们直接使用就可以了。

1 起步依赖

为什么我们只需要引入一个 web 开发的起步依赖,web 开发所需要的所有的依赖都有了呢?

  • 因为 Maven 的依赖传递。
  • 在 SpringBoot 给我们提供的这些起步依赖当中,已提供了当前程序开发所需要的所有的常见依赖(官网地址:https://docs.spring.io/spring-boot/docs/2.7.7/referen
    ce/htmlsingle/#using.build-systems.starters )。
  • 比如:springboot-starter-web,这是 web 开发的起步依赖,在 web 开发的起步依赖当中,就集成了 web 开发中常见的依赖:json、web、webmvc、tomcat等。我们只需要引入这一个起步依赖,其他的依赖都会自动的通过 Maven 的依赖传递进来。

结论:起步依赖的原理就是 Maven 的依赖传递。

2 自动配置

2.1 概述

SpringBoot 的自动配置就是当 spring 容器启动后,一些配置类、bean 对象就自动存入到了 IOC 容器中,不需要我们手动去声明,从而简化了开发,省去了繁琐的配置操作。

2.2 方案一,@ComponentScan 组件扫描

@ComponentScan({"com.example","com.itheima"})
@SpringBootApplication
public class SpringbootWebConfig2Application {
}

缺点:

  1. 使用繁琐
  2. 性能低

2.3 方案二,@Import 导入

使用 @Import 导入的类会被Spring加载到IOC容器中,导入形式主要有以下几种:

  1. 导入 普通类
  2. 导入 配置类
  3. 导入 ImportSelector 接口实现类
  4. @EnableXxxx 注解,封装 @Import 注解
//@Import({TokenParser.class})//导入普通类,交给IOC容器管理
//@Import({HeaderConfig.class})//导入配置类,交给IOC容器管理
@Import({MyImportSelector.class})//导入ImportSelector接口实现类,交给IOC容器管理
@SpringBootApplication
public class SpringbootWebConfig2Application {public static void main(String[] args) {SpringApplication.run(SpringbootWebConfig2Application.class, args);}
}
@EnableHeaderConfig
@SpringBootApplication
public class SpringbootWebConfig2Application {public static void main(String[] args) {SpringApplication.run(SpringbootWebConfig2Application.class, args);}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(MyImportSelector.class)
public @interface EnableHeaderConfig {
}public class MyImportSelector implements ImportSelector {public String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{"com.example.HeaderConfig"};}
}

2.4 原理分析

2.4.1 源码跟踪

在这里插入图片描述
@SpringBootApplication
该注解标识在 SpringBoot 工程引导类上,是 SpringBoot 中 最最最重要 的注解。该注解由三个部分组成:

  1. @SpringBootConfiguration:该注解与 @Configuration 注解作用相同,用来声明当前也是一个配置类。
  2. @ComponentScan:组件扫描,默认扫描当前引导类所在包及其子包。
  3. @EnableAutoConfiguration:SpringBoot 实现自动化配置的核心注解。

在这里插入图片描述

2.4.2 @Conditional
  • 作用:按照一定的条件进行判断,在满足给定条件后才会注册对应的 bean 对象到 Spring IOC 容器中。
  • 位置:方法、类
  • @Conditional 本身是一个父注解,派生出大量的子注解:
    1️⃣@ConditionalOnClass:判断环境中是否有对应字节码文件,才注册 bean 到 IOC 容器。
    2️⃣ @ConditionalOnMissingBean:判断环境中没有对应的 bean(类型 或 名称) ,才注册 bean 到 IOC 容器。
    3️⃣ @ConditionalOnProperty:判断配置文件中有对应属性和值,才注册 bean 到 IOC 容器。

在这里插入图片描述

@Configuration
public class HeaderConfig {@Bean@ConditionalOnClass(name = "io.jsonwebtoken.Jwts")// 环境中存在指定的这个类,才会将该bean加入IOC容器public HeaderParser headerParser1(){return new HeaderParser();}@Bean
//    @ConditionalOnMissingBean //当不存在当前类型(HeaderGenerator)的bean时,才声明该bean
//    @ConditionalOnMissingBean(name = "deptController2") //不存在指定名称的bean,才会将该bean加入IOC容器@ConditionalOnMissingBean(HeaderConfig.class)//不存在指定类型的bean,才会将bean加入IOC容器public HeaderGenerator headerGenerator(){return new HeaderGenerator();}@Bean@ConditionalOnProperty(name = "name" ,havingValue = "itheima")//配置文件中存在指定的属性与值,才会将该bean加入IOC容器public HeaderParser headerParser2(){return new HeaderParser();}}

2.5 案例

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

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

相关文章

R语言实现多要素偏相关分析

偏相关分析是指当两个变量同时与第三个变量相关时&#xff0c;将第三个变量的影响剔除&#xff0c;只分析另外两个变量之间相关程度的过程&#xff0c;判定指标是相关系数的R值。 在GIS中&#xff0c;偏相关分析也十分常见&#xff0c;我们经常需要分析某一个指数与相关环境参…

clickhouse突然启动不起来问题排查

场景&#xff1a; 在实现postgreql数据迁移到clickhouse中&#xff0c;想使用MaterializedPostgreSQL的功能实现&#xff0c;但是中途clickhouse突然挂了&#xff0c;就再启动不了了。 现象&#xff1a; systemctl start clcikhouse-server启动报错 [rootlocalhost clickhous…

理清大数据技术与架构

大数据并不是一个系统软件&#xff0c;更不是一个单一的软件&#xff0c;它实际上是一种技术体系、一种数据处理方法&#xff0c;甚至可以说是一个服务平台。在这个技术体系中&#xff0c;涵盖了许多不同的部件&#xff0c;比如Hadoop服务平台。这一服务平台可以根据具体情况自…

HarmonyOS ArkTS 通用事件(二十三)

通用事件目录 点击事件事件ClickEvent对象说明EventTarget8对象说明示例 触摸事件事件TouchEvent对象说明TouchObject对象说明示例 挂载卸载事件事件示例 点击事件 组件被点击时触发的事件。 事件 ClickEvent对象说明 从API version 9开始&#xff0c;该接口支持在ArkTS卡片中…

02、JS实现:使用二分查找实现两数相除的算法(要求:不使⽤乘法、除法和 mod 运算符)

二分查找实现两数相除的算法 Ⅰ、两数相除&#xff1a;1、题目描述&#xff1a;2、解题思路&#xff1a;3、实现代码&#xff1a; Ⅱ、小结&#xff1a; Ⅰ、两数相除&#xff1a; 1、题目描述&#xff1a; 给定两个整数&#xff0c;被除数 dividend 和除数 divisor。将两数相…

Oracle 部署及基础使用

1. Oracle 简介 Oracle Database&#xff0c;又名 Oracle RDBMS&#xff0c;简称 Oracle Oracle系统&#xff0c;即是以Oracle关系数据库为数据存储和管理作为构架基础&#xff0c;构建出的数据库管理系统。是目前最流行的客户/服务器&#xff08;client/server&#xff09;或…

8种Kubernetes集群中Pod处于 Pending状态的故障排除方法

文章目录 一、Pod与容器二、Pod的阶段&#xff08;状态&#xff09;三、Pod 状态故障排除3.1 检查 Pod 事件3.2 检查资源可用性3.3 检查污点和容忍度3.4 检查节点亲和性设置3.5 检查持久卷声明3.6 检查配额和限制3.7 验证 Pod 和容器映像3.8 分析调度程序日志 四、用于排查 Pen…

html中如何让网页禁用右键禁止查看源代码

在网页中&#xff0c;辛辛苦苦写的文章&#xff0c;被别人复制粘贴给盗用去另很多站长感到非常无奈&#xff0c;通常大家复制都会使用选取右键复制&#xff0c;或CTRLC等方式&#xff0c;下面介绍几种禁止鼠标右键代码&#xff0c;可减少网页上文章被抄袭的几率&#xff0c;当然…

机器学习——终身学习

终身学习 AI不断学习新的任务&#xff0c;最终进化成天网控制人类终身学习&#xff08;LLL&#xff09;&#xff0c;持续学习&#xff0c;永不停止的学习&#xff0c;增量学习 用线上收集的资料不断的训练模型 问题就是对之前的任务进行遗忘&#xff0c;在之前的任务上表现不好…

用C语言打造自己的Unix风格ls命令

在Unix或类Unix操作系统中&#xff0c;ls是一个非常基础且实用的命令&#xff0c;它用于列出当前目录或指定目录下的文件和子目录。下面&#xff0c;我们将通过C语言编写一个简化的ls命令&#xff0c;展示如何利用dirent.h头文件提供的函数接口实现这一功能。 #include "…

发布镜像到阿里云仓库

发布上一篇Dockerfile实战-自定义的centos镜像。 1、登录阿里云 2、找到容器镜像服务 3、创建命令空间 4、创建镜像仓库 5、点击进入这个镜像仓库&#xff0c;可以看到所有的信息 6、根据操作指南测试推送发布 6.1登录阿里云 [rootzhoujunru home]# docker login --usernam…

开箱即用之 windows部署jdk、设置nginx、jar自启

jdk安装 官网下载对应的安装包&#xff0c;解压之后放在本地指定的文件夹下 传送门https://www.oracle.com/java/technologies/downloads/#jdk21-windows 我比较喜欢下载zip方式的&#xff0c;解压之后直接能用&#xff0c;不需要安装了 配置环境 JAVA_HOME 添加path路径 …

Nebula Graph-01-Nebula Graph简介和安装以及客户端连接

前言 NoSQL 数据库 图数据库并不是可以克服关系型数据库缺点的唯一替代方案。现在市面上还有很多非关系型数据库的产品&#xff0c;这些产品都可以叫做 NoSQL。NoSQL 一词最早于上世纪 90 年代末提出&#xff0c;可以解释为“非 SQL” 或“不仅是 SQL”&#xff0c;具体解释要…

蓝桥练习题总结(一)字母图形、完美的代价、01串、序列求和

目录 一、字母图形 二、完美的代价 三、01字串 四、序列求和 一、字母图形 问题描述 利用字母可以组成一些美丽的图形&#xff0c;下面给出了一个例子&#xff1a; ABCDEFG BABCDEF CBABCDE DCBABCD EDCBABC 这是一个5行7列的图形&#xff0c;请找出这个图形的规律&#xff…

本地gitlab-runner的创建与注册

引言 之前通过一些方式在本地创建runner&#xff0c;时而会出现一些未知的坑&#xff0c;所以写下本文记录runner可以无坑创建的方式。 以下注册runner到相应仓库的前提是已经在本地安装了gitlab-runner 具体安装方式见官网 本地gitlab-runner安装常用的指令 查看gitlab r…

SQLiteC/C++接口详细介绍之sqlite3类(十八)

返回目录&#xff1a;SQLite—免费开源数据库系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;十七&#xff09; 下一篇&#xff1a;SQLiteC/C接口详细介绍sqlite3_stmt类&#xff08;一&#xff09; ​ 56.sqlite3_update_hook 函数功能&am…

Vue.js前端开发零基础教学(二)

目录 前言 2.1 单文件组件 2.2 数据绑定 2.2.2 响应式数据绑定 2.3 指令 2.3.1 内容渲染指令 2.3.2 属性绑定指令 ​编辑 2.3.3 事件绑定指令 2.3.4 双向数据绑定指令 2.3.5 条件渲染指令 2.3.6 列表渲染指令 2.4 事件对象 2.5 事件修饰符 学习目标&am…

【CKA模拟题】学会JSONPath,精准定位Pod信息!

题干 For this question, please set this context (In exam, diff cluster name) kubectl config use-context kubernetes-adminkubernetesyou have a script named pod-filter.sh . Update this script to include a command that filters and displays the label with the…

STM32-DMA数据转运

DMA进行转运的条件 1&#xff1a;开关控制&#xff0c;DMA_CMD必须使能2&#xff1a;传输计数器必须大于03&#xff1a;触发源必须有触发的信号

【c++】c++背景(c++的前世今生)

主页&#xff1a;醋溜马桶圈-CSDN博客 专栏&#xff1a;c_醋溜马桶圈的博客-CSDN博客 gitee&#xff1a;mnxcc (mnxcc) - Gitee.com 目录 1. 什么是C 2. C发展史 3. C的重要性 3.1 语言的使用广泛度 3.2在工作邻域 1. 操作系统以及大型系统软件开发 2. 服务器端开发 3. …