SpringBoot学习(三)数据访问、基础特性、核心原理

文章目录

  • 数据访问
    • 示例
    • 自动配置原理
      • jdbc场景自动配置数据源等基本信息
      • `MyBatisAutoConfiguration`配置MyBatis整合流程
  • 基础特性
    • `SpringApplication`
      • 自定义`banner`
      • 自定义`SpringApplication`
      • FluentBuilder API
    • Profiles
      • 使用
        • 指定环境
        • 环境激活
        • 环境包含
      • Profiles配置文件
    • 外部化配置
      • 配置优先级
      • 外部配置
      • 导入配置
      • 属性占位符
    • 单元测试-JUnit5
      • 整合
      • 测试
        • 注解
        • 断言
  • 核心原理
    • 事件和监听器
      • 生命周期监听
        • 监听器
        • 生命周期全流程
      • 事件触发时机
        • 各种回调监听器
        • 完整触发流程
        • SpringBoot事件驱动开发
    • 自动配置原理
      • 入门
        • 自动配置流程
        • SPI机制
        • 功能开关
      • 进阶
        • `@SpringBootApplication`
        • 完整启动加载流程
    • 自定义`starter`
      • 业务代码
      • 基本抽取
      • 使用`Enable`机制
      • 完全自动

数据访问

整个SSM场景:Spring、SpringMVC、MyBatis

示例

  1. 依赖
<!--ssm-->
<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.1</version>
</dependency>
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.30</version><scope>runtime</scope>
</dependency>
  1. 数据库配置资源
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.url=jdbc:mysql://localhost:3306/ssm
spring.datasource.username=root
spring.datasource.password=root
  • 可用MyBatisX插件,帮助生产Mapper接口的xml文件
  1. 配置MyBatis
# 指定mapper映射文件位置
mybatis.mapper-locations=classpath:/mapper/*.xml
# 参数项调整为驼峰命名,便于匹配字段与数据项
mybatis.configuration.map-underscore-to-camel-case=true
  1. CRUD
  • 每个方法都应在Mapper文件中有一个sql标签与之对应
  • 所有参数都应用@Param进行签名,以后使用指定签名在SQL中取值
  • 使用@MapperScan(批量扫描)告知MyBatis,扫描哪个包下的所有接口
  • 使用mybatis.mapper-locations告知MyBatis,接口对应的xml文件在哪里
  • MyBatis自动关联由接口全类名等同namespace值来实现
  • sql写在xml中,mybatis配置写在application.properties

自动配置原理

jdbc场景自动配置数据源等基本信息

  1. mybatis-spring-boot-starter导入spring-boot-starter-jdbc作为操作数据的场景
  2. 默认配置类:
  • org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration:
  • 数据源的自动配置
  • 所有和数据源有关的配置都绑定在DataSourceProperties
  • 默认使用HikariDataSource
  • org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration
  • 向容器中放置了JdbcTemplate以操作数据库
  • org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration
  • org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration:
  • 基于XA二阶提交协议的分布式事务数据源
  • org.springframework.boot.autoconfigure.jdbc.DataSourceTransacitonManagerAutoConfiguration:
  • 支持事务
  1. 底层能力:数据源、JdbcTemplate、事务

MyBatisAutoConfiguration配置MyBatis整合流程

  1. mybatis-spring-boot-starter导入mybatis-spring-boot-autoconfigure(mybatis的自动配置包)
  2. 默认配置类:
  • org.springframework.boot.autoconfigure.MybatisLanguageDriverAutoConfiguration
  • org.springframework.boot.autoconfigure.MybatisAutoConfiguration:
  • 必须在数据源配置成功后才进行配置
  • 向容器中放置SqlSessionFactory组件,创建和数据库的一次会话
  • 向容器中放置SqlSessionTemplate组件,操作数据库
  1. MyBatis的所有配置绑定在MyBatisProperties
  2. 利用@MapperScan原理,将Mapper接口的代理对象创建并放入容器:
  • 利用@Import(MapperScannerRegister.class)批量向容器中注册组件,解析指定包路径中的所有类,为所有Mapper接口类创建Bean信息,并注册到容器中

基础特性

SpringApplication

自定义banner

  1. 类路径添加banner.txt或设置spring.banner.location可以设置banner样式
  2. spring.main.banner-mode=off可以快速关闭banner

自定义SpringApplication

@SpringBootApplication
public class MyApplication {public static void main(string[] args) {SpringApplication application = new SpringApplication(MyApplication.class);application.setBannerMode(Banner.Mode.OFF);application.run(args);}
}

FluentBuilder API

new SpringApplicationBuilder().sources(Parent.class).child(Application.class).bannerMode(Banner.Mode.OFF).run(args);

Profiles

期待快速切换开发、测试、生产环境的环境隔离能力:

  1. 标识环境:指定对应组件、配置在对应位置生效
  2. 切换环境:使用特定环境时,对应的所有组件和配置则生效

使用

指定环境
  1. Spring Profiles提供一种隔离配置的方式,使其仅在特定环境下生效
  2. 任何@Component@Configuration@ConfigurationProperties都可以使用@Profile进行标记,指定何时被加载
@Profile({"test"})
  1. 不被@Profile标记的组件代表任意时刻都生效,不区分环境
环境激活
  1. 配置激活环境
spring.profiles.active=production,hsqldb
or
spring.profiles.active[0]=production
spring.profiles.active[1]=hsqldb
  1. 命令行激活
java -jar xxx.jar --spring.profile.active=development,hsqldb
  1. 配置默认环境,未指明时使用该环境对应组件和配置(推荐使用激活方式选择场景,而非指定默认方式固定使用某个场景)
spring.profiles.default=test
环境包含
  1. 包含场景:无论在何种情况下都会生效的场景
spring.profiles.include=test, development
  1. spring.profiles.activespring.profiles.default只能用到无profile的文件中,若在application-test.yaml中编写则是无效指令
  2. 可以额外添加生效文件,而非激活替换
spring.profiles.include[0]=common
spring.profiles.include[1]=local
  1. 最终生效的场景 = 激活/默认场景 + 包含场景
  2. 在项目中:
  • 基础的配置mybatislogxxx等写入包含场景
  • 动态切换变化的配置dbredis等写入激活/默认场景

Profiles配置文件

  1. application.properties主配置文件,任何情况下生效
  2. 命名规范:application-{profile标识}.properties
  3. 激活指定场景使用,项目生效配置 = 激活场景配置文件的所有项 + 主配置文件和激活文件不冲突的所有项(冲突项以激活场景配置文件为准)

外部化配置

线上应用快速修改配置,至最新配置

  • SpringBoot使用 配置优先级+外部配置 简化配置更新、简化运维
  • 给jar应用所在文件夹放置application.properties最新配置文件,重启项目即可自动应用最新配置

配置优先级

SpringBoot允许将配置外部化,以便在不同环境中使用相同的应用程序代码

  1. 对SpringBoot属性源的加载顺序,优先级顺序为(数字与优先级相反):
优先级属性原
14默认属性(通过SpringApplication.setDefaultProperties指定)
13@PropertySource指定加载配置(需写在@Configuration类上)
12配置文件(`application.properties/yml等)
11RandomValuePropertySource支持的random.*配置(eg.`@Value("$(random.int)*))
10OS环境变量
9Java系统属性(System.getProperties()
8JNDI属性(来自java:comp/env
7ServletContext初始化参数
6ServletConfig初始化参数
5SPRING_APPLICATION_JSON属性(内置在环境变量或系统属性中的JSON)
4命令行参数
3测试属性(@SpringBootTest测试时指定的属性)
2测试类@TestPropertySource注解
1Devtools设置的全局属性($HOME/.config/spring-boot
  1. 常用
  • 命令行 > 配置文件 > springapplication配置
  • 配置文件的优先级:
  • 包外 > 包内;
  • profile > application
  • .properties > .yml
  • config目录 > 根目录

外部配置

在这里插入图片描述

导入配置

#导入额外配置,值总是优先于文件内部编写的值
spring.boot.import=classpath:/*.properties

属性占位符

#去除曾配置过的项的值
#Unknown代表默认值,选填
app.name=MyApp
app.description={$name:dault} is a Spring Boot application written by ${username:Unknown)

单元测试-JUnit5

整合

SpringBoot存在一系列测试工具及注解方便用户调用测试
spring-boot-test提供核心测试能力、spring-boot-test-autoconfigure提供部分测试配置

<!--test单元测试-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency>

测试

组件测试,直接使用@Autowired容器组件注入

注解
注解用法
@Test标识为测试方法,但不同于Junit4的同名注解,该注解不能声明任何属性,拓展测试将由Jupiter提供额外测试进行
@Parameterized标识参数化测试方法
@Repeated标识可重复执行方法
@DisplayName为测试类或测试方法设置展示名
@BeforeEach表示在每个单元测试前执行
@AfterEach表示在每个单元测试后执行
@BeforeAll表示在所有单元测试前执行
@AfterAll表示在所有单元测试后执行
@Tag标识单元测试类型,类似于Junit4的@Categories
@Disabled标识不执行该测试类或测试方法,类似于Junit4的@Ignore
@Timeout标识测试方法最大运行时间及超时会返回错误
@ExtendWith测试类或测试方法拓展类引用
断言
方法说明
assertEquals判断两个对象或两个原始类型是否相等
assertNotEquals判断两个对象或两个原始类型是否不相等
assertSame判断两个对象引用是否值相同对象
assertNotSame判断两个对象引用是否值不同对象
asserTrue判断给定布尔值是否为true
asserFalse判断给定布尔值是否为false
asserNull判断给定对象引用是否为null
asserNotNull判断给定对象引用是否不为null
assertArrayEquals数组断言
assertAll组合断言
assertThrows异常断言
assertTimeout超时断言
fall快速失败

核心原理

事件和监听器

生命周期监听

监听应用的生命周期

监听器
  1. 自定义SpringApplicationRunListener来监听事件:
  • 编写SpringApplicationRunListener实现类
  • META-INF/spring.factories中配置org.springframework.boot.SpringApplicationRunListener=个人Listener,还可指定一个有参构造器,接受参数(SpringApplication application, String[] args)
  • SpringBoot在spring-boot.jar中配置了默认Listener:
  • org.springframework.boot.SpringApplicationRunListener=\
  • org.springframework.boot.context.event.EventPublishingRunListener
  1. 引导:利用 BootstrapContext 引导整个项目启动
  • starting:应用开始,SpringApplicationrun 方法调用,只要存在 BootstrapContext 就执行
  • environmentPrepared:环境准备完毕(将启动参数等绑定到环境变量中),但IoC还未创建
  1. 启动:
  • contextPrepared:IiC容器创建且准备完毕,但主配置类sources未加载,关闭引导启动器
  • contextLoaded:IoC容器与主配置类加载完毕,但IoC容器还未刷新(Bean还未创建)
  • started:IoC容器刷新(Bean准备完毕),但runner未调用
  • ready:IoC容器刷新(Bean准备完毕),runner调用完毕
  1. 运行:步骤正确执行后,容器开始running
生命周期全流程

在这里插入图片描述

事件触发时机

各种回调监听器
  1. BootstrapRegistryInitializer:感知遇到初始化阶段
  • META-INF/spring.factories
  • 创建引导上下文bootstrapContext的时候触发
  • 场景:进行密钥校对授权
  1. ApplicationContextInitializer:感知IoC容器初始化阶段
  • META-INFO/spring.factories
  1. ApplicationListener:感知全阶段,基于事件机制感知事件,处于某个阶段允许执行对应操作
  • @Bean@EventListener:事件驱动
  • SpringApplication.addListeners()SpringApplicationBuilder.listeners()
  • META-INF/spring.factories
  1. SpringApplicationRunListener:感知全阶段,在任意阶段都能够自定义操作,更加完善的功能覆盖面
  • META-INF/spring.factories
  1. ApplicationRunner:感知特定阶段,感知到应用就绪时Ready;感知到应用卡死,不进入就绪
  • @Bean
  1. CommandLineRunner:感知特定阶段,感知到应用就绪时Ready;感知到应用卡死,不进入就绪
  • @Bean
  • 示例:
  • 若项目启动前操作:BootstrapRegistryInitializerApplicationContextInitializer
  • 若项目启动后操作:ApplicationRunnerCommandLineRunner
  • 若要干涉生命周期操作:SpringApplicationRunListener
  • 若要使用事件机制:ApplicationListener
完整触发流程
事件触发时机
ApplicationStartingEvent应用启动但未做任何操作,越过注册listeners and initializers
ApplicationEnvironmentPreparedEvent环境准备好,但context未创建
ApplicationContextInitializedEventApplicationContext准备好,ApplicationContextInitializers调用,单位加载任何Bean
ApplicationPreparedEvent容器刷新之前,Bean定义信息加载
ApplicationStartedEvent容器刷新完成,runner未调用
AvailabilityChangeEventLivenessState.CORRECT应用存活—存活探针
ApplicationReadyEvent任何runner被调用
AvailabilityChangeEventReadinessState.ACCEPTING_TRAFFIC接收请求—就绪探针
ApplicationFailedEvent启动出错

在这里插入图片描述

SpringBoot事件驱动开发

应用启动过程生命周期事件感知(9种给定情况)、应用运行中事件感知(无数种自定义)

  • 事件发布:ApplicationEventPublishAware或注入ApplicationEventMulticaster
  • 事件监听:组件 + @EventListener
    在这里插入图片描述

自动配置原理

入门

应用关注核心:场景、配置、组件

自动配置流程
  1. 导入starter
  2. 导入依赖autoconfigure
  3. 寻找类路径META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件
  4. 加载所有自动配置类*AutoConfiguration
  • 给容器中配置功能组件
  • 组件参数绑定到属性类中*Properties
  • 属性类和配置文件前缀绑定
  • @Conditional派生条件注解判定组件是否生效
  1. 效果:
  • 修改配置文件、底层参数
  • 所有场景自动配置直接使用
  • 可注入SpringBoot准备好的组件直接使用
SPI机制
  1. SPI(Service Provider Interface)是一种软件设计模式,用于在应用程序中动态发现和加载组件
  2. SPI思想定义一个接口或抽象类,再通过classpath中定义好的实现该接口的类,解决对组件的动态发现和加载
  3. Java中SPI由META-INF/services目录下创建一个以服务接口全限定名为名的文件,其中包含实现该服务接口的类的全限定名,Java SPI会自动扫描classpath并根据文件中指定的类名来加载实现类
  4. SPI机制使得程序更加灵活、可扩展,同时增加代码可维护性和避免硬编码依赖关系
功能开关
  1. 自动配置:自动化,项目启动时spi文件指定的所有内容都加载
  2. @Enable*:手动控制开启*功能,利用@Import将需要的功能单独导入

进阶

@SpringBootApplication
  1. @SpringBootConfiguration:就是@Configuration,容器中的组件、配置类,spring IoC启动即创建该类对象
  2. @EnableAutoConfiguration:开启自动配置
  3. @AutoConfigurationPackage:扫描主程序包:加载自身的组件
  • 利用@Import(AutoConfigurationPackages.Registrar.class)给容器中导入需要的组件
  • 把主程序所在的包的所有组件都导入进来
  1. @Import(AutoConfigurationImportSelector.class):加载所有自动配置类:starter导入的组件
  2. @ComponentScan:组件扫描,排除已扫描进来的非必要配置类和自动配置类
完整启动加载流程

在这里插入图片描述

自定义starter

  1. 创建自定义starter项目,引入spring-boot-starter依赖
  2. 编写模块功能,并引入模块所需依赖,编写*AutoConfiguration自动配置类
  3. 编写配置文件META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports,指定启动时需要加载的自动配置
  4. 等待其他项目引入

业务代码

自定义配置显示提示:导入依赖并重启项目,再次填写配置文件时跳出补完提示

<!--导入配置处理器,使配置文件properties配置显示补完提示-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional>
</dependency>
@ConfigurationProperties(prefix="robot")//此属性类和配置文件指定前缀绑定
@Component
@Data
public class RobotProperties {private String name;private String emial;
}

基本抽取

  1. 创建starter项目,把公共代码需要的所有依赖导入
  2. 复制公共代码
  3. 自定义一个RobotAutoConfiguration,向容器中放置该场景所需的所有组件(因为starter所在的包和引入它的项目的主程序所在的包并非父子层级,所有这些组件不会被默认扫描到)
  4. 其他用户引用该starter时,直接导入这个RobotAutoConfiguration,就能将该场景的组件导入

使用Enable机制

其他用户引用该starter时,使用@EnableRobot开启对应功能

@Retention(RetentionPolicy.RUNTIME)
@Target({ElemenType.TYPE})
@Documented
@Import(RobotAutoConfiguration.class)
public @interface EnableRobot {...}

完全自动

依赖SpringBoot的SPI机制

  • META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中编写好自定义的自动配置类的全类名
  • 项目启动时,自动加载声明的自动配置类

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

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

相关文章

选择最佳 PoE 布线系统的 3 个步骤

选择合适的 POE 布线系统的重要性 在不断发展的信息和通信技术 &#xff08;ICT&#xff09; 领域&#xff0c;以太网供电 &#xff08;PoE&#xff09; 布线系统已成为一种革命性的解决方案&#xff0c;它简化了网络设备的部署和管理&#xff0c;同时优化了电力传输。从智能建…

基于ARX结构(模加运算循环移位异或运算)的密码杂凑算法Lemon512

基于ARX结构(模加运算&循环移位&异或运算)的密码杂凑算法Lemon512 黄金龙 QQ1435271638 密码杂凑算法 密码杂凑算法也称作“散列算法”或“哈希算法”,现在的密码行业标准统称其为密码杂凑算法,简称“杂凑算法”或“杂凑函数”。密码杂凑算法对任意长度的消息进行…

汽车零部件制造迎来智能化升级,3D视觉定位系统助力无人化生产线建设

随着新能源汽车市场的蓬勃发展&#xff0c;汽车零部件制造行业正面临着前所未有的机遇与挑战。为了提高产能和产品加工精度&#xff0c;某专业铝合金汽车零部件制造商决定引进智能生产线&#xff0c;其中&#xff0c;对成垛摆放的变速箱壳体进行机床上料成为关键一环。 传统的上…

Postgresql源码(125)游标恢复执行的原理分析

问题 为什么每次fetch游标能从上一次的位置继续&#xff1f;后面用一个简单用例分析原理。 【速查】 恢复扫描需要知道当前页面、上一次扫描到的偏移位置、当前页面一共有几条&#xff1a; 当前页面&#xff1a;HeapScanDesc结构中记录了扫到的页面&#xff08;scan->rs_cb…

WPF中DataGrid主从数据(父子数据)展示

在wpf中可以使用DataGrid控件,进行主从数据展示,也称父子数据展示。下面展示纯原生控件编码实现功能(样式自己可以根据需求进行修改)。 效果如下: 点击图标,展开和收缩可以自由的切换,也可以自己重新写一个样式,比如+,-或者类似图标的样式,都是可以的。 1.首先创建一…

视频制作|专业人做专业事,分分钟剪出“薪”高度

随着视频的蓬勃发展&#xff0c;很多企业都有了通过视频传递企业信息和宣传企业形象的需求&#xff0c;如短视频、长视频、品宣视频、产品视频等。在了解短视频制作的好处与用途之后&#xff0c;视频在各行各业中都有了广泛的应用。 越来越多的企业选择在YesPMP平台将视频制作业…

GT资源-CPLL QPLL

一、前言 QPLL与CPLL是两种为GT Channel提供时钟的锁相环&#xff0c;其中CPLL与GT Channel绑定&#xff0c;每一个通道都有一个CPLL&#xff0c;而QPLL是与Quad绑定&#xff0c;每一个Quad有一个QPLL&#xff0c;4个通道共享一个QPLL 二、CPLL 每个GTX/GTH收发器通道包含一…

Java基础(变量)

什么是变量&#xff1f; 变量&#xff1a;在程序的执行过程中&#xff0c;其值有可能发生改变的量&#xff08;数据&#xff09; 变量的使用场景 当某个数据经常发生改变时&#xff0c;我们也可以用变量储存。当数据变化时&#xff0c;只要修改变量里面记录的值即可。 变量…

iframe嵌入海康威视摄像头监控视频画面

前言&#xff1a;海康威视有非常好的开放平台支持(海康开放平台)&#xff0c;如遇到技术问题&#xff0c;可以先花点时间在开放平台视频教程板块学习一下。直接问客服可能会比较懵&#xff0c;而且sdk客服和api客服互相分离&#xff0c;一开始可能都不知道问谁。 在开放平台上…

linux三剑客精妙招式都汇总在本文了(建议收藏)

熟悉linux的都知道&#xff0c;linux中有著名的三个命令&#xff0c;即grep、sed、awk。这三个命令被称为linux三剑客。三剑客包含各种招式众多&#xff0c;熟练掌握这三个命令的用法&#xff0c;将大大提高我们对文件的处理速度&#xff0c;大大提升运维效率。 本文通过具体实…

Python零基础从小白打怪升级中~~~~~~~TCP网络编程

TCP网络编程 一、什么是TCP协议 TCP( Transmission control protocol )即传输控制协议&#xff0c;是一种面向连接、可靠的数据传输协议&#xff0c;它是为了在不可靠的互联网上提供可靠的端到端字节流而专门设计的一个传输协议。 面向连接 &#xff1a;数据传输之前客户端和…

【环境】原则

系列文章目录 【引论一】项目管理的意义 【引论二】项目管理的逻辑 【环境】概述 【环境】原则 一、培养项目系统性思维 1.1 系统性思维 1.2 系统性思维的价值 1.3 建模和推演&数字孪生 二、项目的复杂性和如何驾驭复杂性 2.1 复杂性的三个维度 2.2 如何驾驭复杂性 三、…