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

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);}
}
public class MyImportSelector implements ImportSelector {public String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{"com.example.HeaderConfig"};}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(MyImportSelector.class)
public @interface EnableHeaderConfig {
}
@EnableHeaderConfig
@SpringBootApplication
public class SpringbootWebConfig2Application {public static void main(String[] args) {SpringApplication.run(SpringbootWebConfig2Application.class, args);}
}

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 案例

2.5.1 自定义 starter 分析

场景
在实际开发中,经常会定义一些公共组件,提供给各个项目团队使用。而在 SpringBoot 的项目中,一般会将这些公共组件封装为 SpringBoot 的 starter。

  • SpringBoot 官方 starter 命名: spring-boot-starter-xxxx
  • 第三组织提供的 starter 命名: xxxx-spring-boot-starter
    在这里插入图片描述
2.5.2 自定义 starter 实现

需求

  • 自定义 aliyun-oss-spring-boot-starter,完成阿里云 OSS 操作工具类 AliyunOSSUtils 的自动配置。
  • 目标:引入起步依赖引入之后,要想使用阿里云OSS,注入 AliyunOSSUtils直接使用即可。

步骤

  1. 创建 aliyun-oss-spring-boot-starter 模块
  2. 创建 aliyun-oss-spring-boot-autoconfigure 模块,在 starter 中引入该模块
  3. 在 aliyun-oss-spring-boot-autoconfigure 模块中的定义自动配置功能,并定义自动配置文件 META-INF/spring/xxxx.imports
    在这里插入图片描述
    (1)在 aliyun-oss-spring-boot-autoconfigure 模块中的定义自动配置功能,并定义自动配置文件 META-INF/spring/xxxx.imports

在 SpringBoot 项目中,并不会去扫描 com.aliyun.oss 这个包,所以注释 @Component 注解。

@Data
//@Component
@ConfigurationProperties(prefix = "aliyun.oss")
public class AliOSSProperties {private String endpoint;private String accessKeyId;private String accessKeySecret;private String bucketName;
  • @Configuration 标识该类为配置类
  • @EnableConfigurationProperties 底层为 @Import
//@Component
@Configuration
@EnableConfigurationProperties(AliOSSProperties.class)
public class AliOSSAutoConfiguration {@Beanpublic AliOSSUtils aliOSSUtils(AliOSSProperties aliOSSProperties){AliOSSUtils aliOSSUtils = new AliOSSUtils();aliOSSUtils.setAliOSSProperties(aliOSSProperties);return aliOSSUtils;}
}

在 aliyun-oss-spring-boot-autoconfigure 模块中的 resources 下,新建自动配置文件:META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.impo
rts

com.aliyun.oss.AliOSSAutoConfiguration 

相关文章:

day14-SpringBoot 原理篇

一、配置优先级 SpringBoot 中支持三种格式的配置文件&#xff1a; 注意事项 虽然 springboot 支持多种格式配置文件&#xff0c;但是在项目开发时&#xff0c;推荐统一使用一种格式的配置 &#xff08;yml 是主流&#xff09;。 配置文件优先级排名&#xff08;从高到低&…...

ChatGPT论文指南|揭秘8大ChatGPT提示词研究技巧提升写作效率【建议收藏】

点击下方▼▼▼▼链接直达AIPaperPass &#xff01; AIPaperPass - AI论文写作指导平台 公众号原文▼▼▼▼&#xff1a; ChatGPT论文指南|揭秘8大ChatGPT提示词研究技巧提升写作效率【建议收藏】 目录 1.写作方法 2.方法设计 3.研究结果 4.讨论写作 5.总结结论 6.书…...

P1563 [NOIP2016 提高组] 玩具谜题

题目传送门 这道题实在是一道水题 话不多说&#xff0c;上代码 #include<iostream> #include<cstring> using namespace std; struct a{int io;//in朝里 out朝外 小人的朝向 string name;//小人的名字 int number;//角色编号 }a[100000]; int main(){int n, m…...

【数据库】数据库语言

1.4 数据库语言 数据库系统提供数据定义语言&#xff08;DDL&#xff09;来定义数据库模式&#xff0c;并提供数据操纵语言&#xff08;DML&#xff09;来表达数据库的查询和更新。 通过一系列特定的DDL语句来说明数据库系统所采用的存储结构和访问方式&#xff0c;这种特定的…...

javascript单例模式字面量定义的接口和匿名函数定义的接口;他们之间访问私有变量和私有函数之间的区别

javascript的单例模式&#xff1a;即只有一个实例&#xff1b; 模块模式是在单例模式上扩展而来的 //这种是字面量定义了单例对象的公共接口&#xff1b; 字面量对象调用私有变更和私有函数 var Book(function(){let name;checkBookfunction(value){namevalue;}return{setNam…...

啥是大语言模型LLM

引言&#xff1a; 在人工智能的世界里&#xff0c;有一种技术正迅速改变我们与机器交流的方式——这就是大语言模型LLM&#xff08;Large Language Model&#xff09;。它们像是拥有海量知识库的超级智能&#xff0c;能够理解和生成人类语言。那么&#xff0c;大语言模型LLM到底…...

vue3之路由导航故障

通常一个导航守卫函数中会发生这四件事之一&#xff1a; 1.通过调用 return false 中断了这次导航 2.通过返回一个新的位置&#xff0c;重定向到其他地方 (例如&#xff0c;return ‘/login’) 3.正常导航到指定路由 4.抛出了一个 Error 检测导航故障 可以使用vue-router提供的…...

Dr4g0n

信息收集 # nmap -sn 192.168.56.0/24 -oN live.nmap Starting Nmap 7.94 ( https://nmap.org ) at 2024-03-04 08:52 CST Nmap scan report for 192.168.56.2 Host is up (0.00012s latency). MAC Address: 00:50:56:FE:B1:6F (VMware) Nmap scan report …...

蓝桥杯每日一题:扫雷

题目来源&#xff1a;第十三届蓝桥杯软件赛省赛 B组 在一个 n n n 行 m m m 列 的方格图中有些位置有地雷, 另外一些位置为空 请为每个空位置标一个整数, 表示周围八个相邻的方格中有多少个地雷 输入 : 输入的第一行包含两个整数 n n n , m m m 第 2 行 到 第 n 1 n 1 n…...

net core API 后台系统操作日志的实现思路

net core API 后台系统操作日志的实现思路 系统操作日志的实现思路主要问题不在于写日志和表结构设计上。 主要问题在识别出哪些数据做了修改。并生成日志。 表中数据列众多,且要监控多个表。如果要监控的每个表都去写代码去监控和转换这样的工作量就会比较大。 如,用户表…...

ORACLE 知识整理

目录 一. 插入指定数量的数据二. 索引2.1 创建索引2.2 删除索引 三. 查询计划四. Oracle SQLPlus常用设置五. 增加删除字段 一. 插入指定数量的数据 ⏹当需要向表中插入若干测试数据的时候&#xff0c;可通过下面这种方式造数据 先从DUAL虚拟表中检索后造出10000条数据后&…...

业务服务:redisson

文章目录 前言一、配置1. 添加依赖2. 配置文件/类3. 注入redission3. 封装工具类 二、应用1. RedisUtils工具类的基本使用 三、队列1. 工具类2. 普通队列3. 有界队列&#xff08;限制数据量&#xff09;4. 延迟队列&#xff08;延迟获取数据&#xff09;5. 优先队列&#xff08…...

面试算法-100-零钱兑换

题目 给你一个整数数组 coins &#xff0c;表示不同面额的硬币&#xff1b;以及一个整数 amount &#xff0c;表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额&#xff0c;返回 -1 。 你可以认为每种硬币的数量是无限的…...

【Leetcode每日一题】 动态规划 - 使用最小花费爬楼梯(难度⭐)(41)

1. 题目解析 题目链接&#xff1a;746. 使用最小花费爬楼梯 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 2.算法原理 一、设定状态表 为了解决这个问题&#xff0c;我们首先要明确一个“状态表”。这个状态表其实就是一个记录…...

Springboot旅游管理系统设计与实现

** &#x1f345;点赞收藏关注 → 私信领取本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#xff0c;希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345;** 一、研究背景…...

c++学习笔记(10)

1. 二分答案是一种常用的算法思想&#xff0c;用于解决一些需要枚举所有可能答案的问题。它的基本思想是将问题的答案范围缩小到一半&#xff0c;然后根据一定的条件判断&#xff0c;再将答案范围缩小到一半&#xff0c;直到找到正确的答案或者确定不存在正确答案为止。 下面…...

Visual Studio - 添加快捷键图标

Visual Studio - 添加快捷键图标 1. Text Editor Toolbar Options -> Add or Remove Buttons -> Customize2. Toolbars3. Commands -> Debug4. Add Command...References 1. Text Editor Toolbar Options -> Add or Remove Buttons -> Customize 2. Toolbars B…...

突破边界:Web3开启数字化社会的新纪元

引言 随着科技的不断进步和数字化社会的发展&#xff0c;Web3正逐渐成为了人们关注的焦点。作为新一代互联网的演进形态&#xff0c;Web3具有突破传统边界、实现去中心化的特点&#xff0c;被认为将开启数字化社会的新纪元。本文将深入探讨Web3的概念、特点、应用场景&#xf…...

docker仓库登录及配置insecure-registries的方法

docker仓库登录及配置insecure-registries的方法 这篇文章主要介绍了docker仓库登录配置insecure-registries的方法,docker客户端如果配置中添加了insecure-registary配置&#xff0c;就不需要在docker 客户端配置上对应证书&#xff0c;如果不配置要在/etc/docker/certs.d/目…...

Lambda函数与Selenium WebDriverWait类一起使用

Lambda函数是一种匿名函数&#xff0c;也称为内联函数或者lambda表达式。它们在Python中用于创建简短的、一次性的函数。Lambda函数通常用于在代码中传递函数作为参数&#xff0c;或者在需要一个简单的函数&#xff0c;但不想正式定义一个函数的情况下使用。 Lambda函数的特点…...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...