springboot学习01-[springboot介绍、配置文件介绍、自动配置读取原理]

springboot介绍、配置文件介绍、自动配置读取原理

  • springBoot学习
    • 代码说明
      • 为什么java -jar springJar包后项目就可以启动
  • 配置文件介绍
    • 配置文件加载顺序
    • 其他约定配置文件加载顺序
    • profile配置文件加载
    • 配置文件绑定类属性
      • 通过@Value的方式进行属性注入
      • 通过@ConfigurationProperties的方式进行属性注入
      • 配置文件占位符
      • 配置文件-属性注入:数据校验
      • 通过@PropertySource可以引入外部properties配置文件
  • Springboot自动配置底层原理
    • springboot配置读取原理
      • 这些注解里面最主要的就是@EnableAutoConfiguration
        • @Import({AutoConfigurationImportSelector.class}详细解读
          • process获取配置方法解读
    • 自动配置类原理

springBoot学习

依赖引入

 <properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.target>8</maven.compiler.target><maven.compiler.source>8</maven.compiler.source></properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.6</version></parent><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies><!--打包好帮我们把所有依赖的jar 统统放到jar文件里面的BOOT-INF\lib中设置MANIFEST.MF设置了启动类 .JarLauncher:自定义类加载器加载所有的jar包,调用start-class。从而启动项目--><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>

代码说明

所有的springboot都必须继承spring-boot-starter-parent,通过里面的<artifactId>spring-boot-dependencies</artifactId>帮我们管理了依赖的版本

为什么引入了starter后其他依赖也就被引入了?

一个starter也就是启动器,内置了很多的依赖,就相当于一个聚合,引入一个starter也就都引入了

为什么java -jar springJar包后项目就可以启动

  • 先打包
    在这里插入图片描述
    将打的jar包解压可以看到有个BOOT-INF的,里面还有个lib包这个lib包里存的就是项目依赖的其他jar包,叫fat-jar
    在这里插入图片描述
    META-INF中有个MANIFEST.MF文件,里面的Main-Class是所有的jar文件都有的,这个属性会自定义一个类加载器去加载fat-jar中的jar包。然后调用Start-Class去启动项目
    在这里插入图片描述
    META-INF中的MANIFEST.MF文件中有一个Main-Class属性,这个属性指向了一个自定义的类加载器。这个类加载器在启动Spring Boot应用时会加载fat-jar中的所有依赖,包括starter依赖。
    Start-Class属性则指定了应用启动时要执行的类。通过这种方式,Spring Boot能够在构建的fat-jar中自动寻找并加载所有必要的依赖,从而实现应用的启动。

配置文件介绍

springboot使用一个全局的配置文件 核心配置文件,配置文件名在 约定的情况下 名字是固定的就叫application
配置文件的作用:修改springboot自动配置的默认值;springboot在底层都给我们自动配置好了。比如端口号,springboot默认端口号8080,但是我们可以通过配置文件覆盖默认配置。

配置文件加载顺序

配置文件读取优先级:bootstrap.properties>bootstrap.yml>application.properties>application.yml 优先级大的会覆盖优先级小的

其他约定配置文件加载顺序

1、classpath根目录下
在这里插入图片描述
2、classpath根目录/config
在这里插入图片描述
3、项目根目录
如果当前项目是继承/耦合 关系maven项目的话,项目根目录=父maven项目的根目录。如果是项目只有一个模块那么项目根目录 那就是当前模块的根目录
在这里插入图片描述
4、项目根目录 /config
如果当前项目是继承/耦合 关系maven项目的话,项目根目录=父maven项目的根目录 /config。如果是项目只有一个模块那么项目根目录 那就是当前模块的根目录 /config
在这里插入图片描述
优先级由上到下,由低到高

profile配置文件加载

多环境配置配置文件
profile文件命名规则:application-名称.yml
在这里插入图片描述

  • 在applicaction.yml中进行激活
spring:profiles:active: dev

配置文件绑定类属性

  • 定义实体bean
@Data
@ToString
public class User {private String username;private Integer age;private Date birthday;private List<String> hobbies;private Map<Integer,String> girlFriend;private Address address;
}@Data
public class Address {private Integer id;private String detailAddress;
}
  • 定义yml文件
user:username: zzqage: 25

通过@Value的方式进行属性注入

@Data
@ToString
@Component
public class User {@Value("${user.username}")private String username;@Value("${user.age}")private Integer age;private Date birthday;private List<String> hobbies;private Map<Integer,String> girlFriend;private Address address;
}
  • 测试
@SpringBootTest(classes = MyApplication.class)
public class Test {@Autowiredprivate User user;@org.junit.jupiter.api.Testpublic void test(){System.out.println(user);}
}

在这里插入图片描述

通过@ConfigurationProperties的方式进行属性注入

@Data
@ToString
@Component
@ConfigurationProperties(prefix = "user")
public class User {private String username;private Integer age;private Date birthday;private List<String> hobbies;private Map<Integer,String> girlFriend;private Address address;
}
  • 测试
@SpringBootTest(classes = MyApplication.class)
public class Test {@Autowiredprivate User user;@org.junit.jupiter.api.Testpublic void test(){System.out.println(user);}
}

在这里插入图片描述
@ConfigurationProperties:常用于bean属性和yml配置文件的绑定。prefix:可以指定配置文件中某一个节点,该节点中的子节点将自动和属性进行绑定
此外@ConfigurationProperties还支持松散绑定
在这里插入图片描述
@value和@ConfigurationProperties区别,最大的一个区别就是@ConfigurationProperties可以匹配多个,@value需要一个一个去匹配,比较麻烦

  • 我们目前写yml文件没有提示,如果需要提示需要引入spring-boot-configuration-processor依赖
    这个依赖会生成METE-INFO 元数据 用于提供idea自动提示配置文件的
     <!--这个依赖会生成METE-INFO 元数据 用于提供idea自动提示配置文件的--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><!--依赖不会传播 如果这是个父模块,子模块不会继承这个依赖--><optional>true</optional></dependency>
  • 如果想要自动提示还需要修改idea相关配置
    在这里插入图片描述
    生成的元数据-用于自动提示
    在这里插入图片描述
  • 补充完剩余的属性
  • list类型
  hobbies:- 唱歌- 跳舞- 打篮球hobbies: [唱歌、跳舞、打篮球]

在这里插入图片描述

  • map的类型
  girl-friend:18: 范冰冰19: 刘亦菲girl-friend: {18:范冰冰,19:刘亦菲}

在这里插入图片描述

  • 嵌套对象
  address:id: 5detailAddress: 6666
  • 完整配置
user:username: zzqage: 123birthday: 2020/01/01hobbies:- 唱歌- 跳舞- 打篮球girl-friend: {18:范冰冰,19:刘亦菲}address:id: 6detailAddress: 6666

配置文件占位符

可以通过${}来引用其他的配置项,这就是配置文件占位符,${}还可以引用springboot内置的一些属性,比如random.uuid

user:username: zzqage: 123birthday: 2020/01/01hobbies:- 唱歌- 跳舞- 打篮球girl-friend: {18:范冰冰,19:刘亦菲}address:id: 6detailAddress: ${user.username}的家

id: ${random.int}

user:username: zzqage: 123birthday: 2020/01/01hobbies:- 唱歌- 跳舞- 打篮球girl-friend: {18:范冰冰,19:刘亦菲}address:id: ${random.int}detailAddress: ${user.username}的家

配置文件-属性注入:数据校验

只支持@ConfigurationProperties,在使用的时候只需要加@Validated(支持对jsr-303数据校验)

  • jsr-303数据校验
    在这里插入图片描述
    要支持对jsr-303数据校验还需要加入一个数据校验的场景启动器
 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency>
  • 测试 -实体bean要测试的属性加上注解
@Data
@ToString
@Component
@ConfigurationProperties(prefix = "user")
@Validated
public class User {private String username;private Integer age;private Date birthday;private List<String> hobbies;private Map<Integer,String> girlFriend;@NotNullprivate Address address;
}
  • 配置文件配置-去掉address不让能够注入
user:username: zzqage: 123birthday: 2020/01/01hobbies:- 唱歌- 跳舞- 打篮球girl-friend: {18:范冰冰,19:刘亦菲}

结果在这里插入图片描述

通过@PropertySource可以引入外部properties配置文件

  • properties配置
    在这里插入图片描述
user.username=zzq
user.age=123
user.birthday=2020/02/06
user.hobbies=[跳舞、唱歌]
user.girlFriend.18=范冰冰
user.girlFriend.19=刘亦菲
user.address.id=5
user.address.detailAddress=上海
  • 实体bean配置-@PropertySource(“classpath:data/user.properties”)
@Data
@ToString
@Component
@ConfigurationProperties(prefix = "user")
@Validated
@PropertySource("classpath:data/user.properties")
public class User {private String username;private Integer age;private Date birthday;private List<String> hobbies;private Map<Integer,String> girlFriend;private Address address;
}

Springboot自动配置底层原理

springboot配置读取原理

@SpringBootConfiguration:Spring Boot的配置类:标注在某个类上,表示这是一个Spring Boot的配置类

@Configuration:配置类上来标注这个注解,配置类也是容器的一个组件

@EnableAutoConfiguration:开启自动配置功能:以前我们需要配置的东西,Spring Boot帮我们自动配置;@EnableAutoConfiguration告诉SpringBoot开启自动配置功能,会帮我们自动去加载配置类,这样自动配置才能生效

@ComponentScan:扫描包,如果没有指定扫描包spring底层会自动扫描当前配置类所在的包和子包, TypeExcludeFilter:springboot对外提供的扩展类,可以供我们去按照我们的自定义的方式进行排除。AutoConfigurationExcludeFilter:排除所有实现了AutoConfigurationExcludeFilter 接口 配置类并且自动配置类
在这里插入图片描述

这些注解里面最主要的就是@EnableAutoConfiguration

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";Class<?>[] exclude() default {};String[] excludeName() default {};
}
  • @AutoConfigurationPackage
    这个注解的作用:将当前配置类所在包保存在BasePackages的Bean中。供Sspring内部使用
@Import({AutoConfigurationPackages.Registrar.class}) //保存扫描路径,提供给spring-data-jpa 
public @interface AutoConfigurationPackage {

就是注册了一个保存当前配置类所在包的一个bean

@Import({AutoConfigurationImportSelector.class}详细解读
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {

AutoConfigurationImportSelector是一个实现了DeferredImportSelector的selector类

  • 复习ImportSelector
    作用:返回类路径的完整限定名,并且将这些类注册成bean
    在这里插入图片描述
  • DeferredImportSelector:变种的延迟ImportSelector
    DeferredImportSelector工作原理
    在这里插入图片描述
  • 具体使用
    如果getImportGroup为空则执行importselectors,否则执行getImportGroup返回类的selectImports
public class MyImportSelector implements DeferredImportSelector {@Overridepublic Class<? extends Group> getImportGroup() {return AutoConfigurationGroupdd.class;}@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{"com.springboot.controller.bean.User"};}private static class AutoConfigurationGroupdd implements DeferredImportSelector.Group{AnnotationMetadata metadata;@Overridepublic void process(AnnotationMetadata metadata, DeferredImportSelector selector) {}@Overridepublic Iterable<Entry> selectImports() {List<Entry> list =new ArrayList<>();list.add(new Entry(this.metadata,"com.springboot.controller.bean.Person"));return list;}}
}
process获取配置方法解读

process方法可以获取META-INF/spring.factories里面的内容并把内容给selectorimports方法让这个方法去把spring.factories里面的配置注册成bean
在这里插入图片描述

        //获取spring.factories里面的配置类@Overridepublic void process(AnnotationMetadata metadata, DeferredImportSelector selector) {}//将配置类注册成bean@Overridepublic Iterable<Entry> selectImports() {}

getAutoConfigurationEntry—>getCandidateConfigurations
getCandidateConfigurations再通过spring加载器来获取配置

        List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

自动配置类原理

以HttpEncodingAutoConfiguration为例

@Configuration(proxyBeanMethods = false
)
@EnableConfigurationProperties({ServerProperties.class})
@ConditionalOnWebApplication(type = Type.SERVLET
)
@ConditionalOnClass({CharacterEncodingFilter.class})
@ConditionalOnProperty(prefix = "server.servlet.encoding",value = {"enabled"},matchIfMissing = true
)
public class HttpEncodingAutoConfiguration {private final Encoding properties;public HttpEncodingAutoConfiguration(ServerProperties properties) {this.properties = properties.getServlet().getEncoding();}@Bean@ConditionalOnMissingBeanpublic CharacterEncodingFilter characterEncodingFilter() {CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();filter.setEncoding(this.properties.getCharset().name());filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.web.servlet.server.Encoding.Type.REQUEST));filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.web.servlet.server.Encoding.Type.RESPONSE));return filter;}
}
  • @Configuration( proxyBeanMethods = false)详解
    标记了@Configuration Spring底层会给配置创建cglib动态代理,目的:给标记了@bean的方法在创建bean的时候,会执行动态代理类(这个动态代理类会先从ioc容器里面拿如果拿不到在调用bean方法进行创建,以满足单例模式)
    所以 proxyBeanMethods = false,就不让它去产生代理类
  • @EnableConfigurationProperties({ServerProperties.class})详解
    启用可以在配置类设置的属性 对应的类(在配置文件中可以写哪些属性就由这个配置类中的属性决定)
    启用配置类的属性:里面导入了一个属性配置类
    在这里插入图片描述

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

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

相关文章

力扣62 不同路径

一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路径&#xff1f; 输入&…

FedCache 2.0引领联邦边缘学习性能与通信效率革新

FedCache 2.0引领联邦边缘学习性能与通信效率革新 在今天的数字化时代&#xff0c;边缘计算正迅速成为推动终端设备智能化的核心技术之一&#xff1b;如何在保证数据隐私的同时提高数据在网络边缘的处理效率和效果&#xff0c;已成为业界面临的一大挑战。最近&#xff0c;《Fe…

电巢科技CIOE中国光博会:激光雷达技术应用研讨会圆满落幕!

2024年6月20日&#xff0c;由CIOE中国光博会与电巢科技联合主办的“激光雷达技术应用”线上研讨会成功举行。本次线上研讨会是CIOE中国光博会与电巢科技首次联合主办的论坛&#xff0c;旨在借助双方自身资源优势&#xff0c;为行业发展提供可靠的交流平台。接下来&#xff0c;C…

Android焦点机制结合WMS

文章前提&#xff1a; 了解WMS基本作用了解window的概念&#xff0c;phoneWindow&#xff0c;rootViewImpl了解view的事件分发 开始&#xff1a; 讲三件事情&#xff1a; window的创建&#xff0c;更新焦点的更新事件的分发 Window的创建&#xff0c;更新&#xff1a; wi…

基于 Redis 实现秒杀资格判断,提升并发性能

在互联网电商平台上&#xff0c;秒杀活动往往会吸引大量用户同时抢购&#xff0c;如何高效地处理高并发请求&#xff0c;保证用户体验&#xff0c;是一个重要的技术挑战。本文将介绍如何基于 Redis 实现秒杀资格的判断&#xff0c;提高并发性能。 基本思路 秒杀活动的核心流程…

AI 编程还有前景嘛?

自从各个大厂相继出品 AI 编程助手之后&#xff0c;AI 在编程领域的发展&#xff0c;可谓是几无寸进。 相比于 AI 在多模态领域火热&#xff0c;AI 在编程领域的热度已经完全下来了。 阿七在公众号搜索了关键词「AI编程」&#xff0c;发现搜索出来的公众号寥寥无几&#xff0…

LLM生成模型在生物蛋白质应用:ESM3

参考&#xff1a; https://github.com/evolutionaryscale/esm 通过GPT模型原理&#xff0c;输入蛋白质序列等模态输出预测的蛋白质序列及结构 使用 参考&#xff1a;https://colab.research.google.com/github/evolutionaryscale/esm/blob/main/examples/generate.ipynb#sc…

(六)使用统计学方法进行变量有效性测试(43道选择题)

本文整理了使用统计学方法进行变量有效性测试相关的练习题&#xff0c;共43道&#xff0c;适用于想巩固理论基础的同学。来源&#xff1a;如荷学数据科学题库&#xff08;CDA二级-第7章&#xff09;。 1&#xff09; 2&#xff09; 3&#xff09; 4&#xff09; 5&#xff09;…

三分之一的违规行为未被发现

Gigamon 调查显示&#xff0c;随着漏洞的针对性越来越强、越来越复杂&#xff0c;企业在检测漏洞方面也面临越来越大的困难&#xff0c;超过三分之一的企业表示&#xff0c;现有的安全工具无法在漏洞发生时检测到它们。 随着混合云环境变得越来越复杂&#xff0c;以及恶意行为…

云计算基础知识

前言&#xff1a; 随着ICT技术的高速发展&#xff0c;企业架构对计算、存储、网络资源的需求更高&#xff0c;急需一种新的架构来承载业务&#xff0c;以获得持续&#xff0c;高速&#xff0c;高效的发展&#xff0c;云计算应运而生。 云计算背景 信息大爆炸时代&#xff1a…

Linux 标准IO的fopen和fclose

getchar(),putchar() ‐‐‐‐ 一个字符 gets(buf),puts(buf) ‐‐‐‐ 一串字符 scanf(),printf() ‐‐‐‐ 一个字符&#xff0c;一串字符都可以 fopen函数的形式 FILE * fopen(constchar *path , cost char *mode) /* * description : 打开一个文件 * param ‐ path…

进阶篇07——InnoDB引擎介绍

概览 逻辑存储结构 架构 当执行增删改查操作时&#xff0c;操作的是缓冲区的数据&#xff0c;如果缓冲区里没有要操作的数据&#xff0c;就会从磁盘中读取数据加载到缓冲区中&#xff1b;缓冲区的数据会以一定的频率通过后台线程刷新到磁盘中永久存储。 内存结构 磁盘结构 后…

数据结构(Java):顺序表集合类ArrayList

1、线性表 线性表&#xff0c;在逻辑结构上是连续的&#xff08;可理解为连续的一条直线&#xff0c;一对一的关系&#xff09;&#xff0c;而在物理结构上不一定连续&#xff0c;通常以数组和链式结构进行存储。 线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线…

Vue介绍与入门(一篇入门)

Vue.js 是一个流行的 JavaScript 框架&#xff0c;专门用于构建用户界面和单页面应用程序。它简单易学&#xff0c;但功能强大&#xff0c;能够帮助开发者快速构建交互性强的 Web 应用。 本教程旨在帮助那些刚开始学习 Vue.js 的开发者快速入门&#xff0c;并掌握一些基础知识…

【UE5.1 角色练习】12-坐骑——Part2(让角色骑上坐骑)

目录 前言 效果 步骤 一、坐骑的父类 二、将角色附加到坐骑 三、添加坐姿 四、骑上坐骑 五、从坐骑上下来 前言 在上一篇&#xff08;【UE5.1 角色练习】11-坐骑——Part1&#xff08;控制大象移动&#xff09;&#xff09;基础上继续实现角色骑上坐骑的功能。 效果 …

语言的数据结构:树与二叉树(二叉树篇)

语言的数据结构&#xff1a;树与二叉树&#xff08;二叉树篇&#xff09; 前言概念特别的二叉树满二叉树完全二叉树 存储结构顺序存储链式存储 查找方式 前言 上文说到了树&#xff0c;有人认为二叉树是树的每一个分支都有两个子节点。其实这也对。但二叉树在此基础上还做了限…

【QCustomPlot实战系列】QCPGraph区域高亮

使用QCPDataSelection来设置选中的区域&#xff0c;并将QCPGraph的可选择区域设置成QCP::stMultipleDataRanges void AreaPieces::initCustomPlot(QCustomPlot *parentPlot) {QVector<double> x {0, 1, 2, 3, 4, 5, 6, 7, 8};QVector<double> y {200, 560, 750…

《mysql篇》--mysql常用命令

数据库操作 显示当前数据库 show databases;(database 后面要加s) 这行命令用来显示当前有多少个数据库 //mysql中有自带的四个库 创建数据库 create database 数据库名(name); 创建一个数据库 create dabase if not exists <数据库名(name)>; //如果系统有与当前创建…

前端vite+vue3——利用环境变量和路由区分h5、pc模块打包(从0到1)

⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享 前端vitevue3——利用环境变量和路由对前端区分h5和pc模块打包&#xff08;从0到1&#xff09;。 背景&#xff1a; 前端本地开发pc和h5的项目&#xff0c;发布时需要区分开h5和pc的页面 vite Vite 通过在一开始将应…

图片怎么加水印?快来试试这6个图片加水印方法(2024年新)

图片怎么加水印&#xff1f;作为打工人在日常的工作生活中总会遇到各种各样的工作难题&#xff0c;相信从事电商或者是设计等工作的小伙伴们&#xff0c;遇到最多的问题应该就是给图片添加水印了。为什么要给图片加水印&#xff1f;其实给图片加水印最主要的目的是保护我们的图…