SpringBoot初始化

Springboot启动流程

  • 框架初始化
    • 配置资源加载器
    • 配置primarySources
    • 应用环境检测
    • 配置系统初始化器
    • 配置应用监听器
    • 配置main方法所在类

  • 框架启动

  • 自动化装配

初始化器解析

概览

  • 类名: ApplicationContextInitializer
  • 介绍:Spring容器刷新之前执行的一个回调函数
  • 作用: 向Spring Boot容器中注册属性
  • 使用: 继承接口自定义实现

实现方式1

  • 实现ApplicationContextInitializer接口
  • spring.factories内填写接口实现
    • key值: org.springframework.context.ApplicationContextInitializer
    • value值为自定义初始化器的全类名
@Order(1)
public class FirstInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {@Overridepublic void initialize(ConfigurableApplicationContext applicationContext) {ConfigurableEnvironment environment = applicationContext.getEnvironment();environment.setRequiredProperties("mooc");
//        Map<String, Object> map = new HashMap<>();
//        map.put("key1", "value1");
//        MapPropertySource mapPropertySource = new MapPropertySource("firstInitializer", map);
//        environment.getPropertySources().addLast(mapPropertySource);
//        System.out.println("run firstInitializer");}
}

resources/META-INF/spring.factories编写添加:

org.springframework.context.ApplicationContextInitializer=com.mooc.sb2.initializer.FirstInitializer

实现方式2

  • 实现ApplicationContextInitializer接口
  • 在springApplication类初始后设置进去
@Order(2)
public class SecondInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {@Overridepublic void initialize(ConfigurableApplicationContext applicationContext) {ConfigurableEnvironment environment = applicationContext.getEnvironment();Map<String, Object> map = new HashMap<>();map.put("key2", "value2");MapPropertySource mapPropertySource = new MapPropertySource("secondInitializer", map);environment.getPropertySources().addLast(mapPropertySource);System.out.println("run secondInitializer");}
}

设置:

@SpringBootApplication
@MapperScan("com.mooc.sb2.mapper")
public class Sb2Application {public static void main(String[] args) {
//		SpringApplication.run(Sb2Application.class, args);SpringApplication springApplication = new SpringApplication(Sb2Application.class);springApplication.addInitializers(new SecondInitializer());springApplication.run(args);}}

实现方式3

  • 实现ApplicationContextInitializer接口
  • application.properties内填写接口实现
    • key: context.initializer.classes
    • value值为自定义初始化器的全类名
@Order(3)
public class ThirdInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {@Overridepublic void initialize(ConfigurableApplicationContext applicationContext) {ConfigurableEnvironment environment = applicationContext.getEnvironment();Map<String, Object> map = new HashMap<>();map.put("key3", "value3");MapPropertySource mapPropertySource = new MapPropertySource("thirdInitializer", map);environment.getPropertySources().addLast(mapPropertySource);System.out.println("run thirdInitializer");}
}
context.initializer.classes=com.mooc.sb2.initializer.ThirdInitializer

注意事项

  • 都要实现ApplicationContextInitializer接口
  • Order值越小越先执行
  • applicantion.properties中定义的优先于其他方式

工厂加载机制

SpringFactoriesLoader介绍

  • 框架内部使用的通用工厂加载机制
  • 从classpath下多个jar包特定的位置读取文件并初始化类
  • 文件内容必须是kv形式,即properties类型
  • key是全限定名(抽象类 | 接口)、value是实现,多个实现用','分隔

loadFactories流程

源码具体流程:

系统初始化器解析

作用

  • 上下文刷新即refresh方法之前调用
  • 用来编码设置一些属性变量通常用在web环境中
  • 可以通过实现Order接口来进行排序

初始化器总结流程

三种方式:

  • 定义在spring.factories文件中被SpringFactoriesLoader发现注册
  • SpringApplication初始化完毕后手动添加
  • 定义成环境变量被DelegatingApplicationContextInitializer发现注册

所以为什么application.properties中的初始化器不管定义为Order为多少都是最先被加载,因为DelegatingApplicationContextInitializer中的Order设置的是0, 优先加载的始终是DelegatingApplicationContextInitializer中的初始化器

最后推荐使用spring.factories的方式定义初始化器

面试题

  • 介绍下SpringFactoriesLoader?
    • 就是一个SpringBoot的一个工厂加载类, 用它来完成我们扩展点的实现的载入
  • SpringFactoriesLoader如何加载工厂类?
    • 读取指定路径下的指定文件(META/spring.factories文件),将他们读取成一个properties对象,依次遍历我们的文件内容,将其组装成我们的类名以及对应的实现来依次遍历它, 通过Order进行排序
  • 系统初始化器的作用?
    • SpringBoot容器的一个回调接口, 可以通过它以编码形式的定义我们容器中的属性
  • 系统初始化器的调用时机?
    • 是在SpringBoot.run()方法当中的prepareContext()中的applyInitializers()方法中进行调用的
  • 如何自定义实现系统初始化器?
    • 上面三种实现方式
  • 自定义实现系统初始化器有哪些注意事项?
    • 主要是Order值的大小排序问题, 以及不同的实现方式导致Order值失效的问题

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

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

相关文章

Kafka快速入门

文章目录 Kafka快速入门1、相关概念介绍前言1.1 基本介绍1.2 常见消息队列的比较1.3 Kafka常见相关概念介绍 2、安装Kafka3、初体验前期准备编码测试配置介绍 bug记录 Kafka快速入门 1、相关概念介绍 前言 在当今信息爆炸的时代&#xff0c;实时数据处理已经成为许多应用程序和…

【开源】基于Vue.js的校园二手交易系统的设计和实现

目录 一、摘要1.1 项目介绍1.2 项目详细录屏 二、功能模块2.1 数据中心模块2.2 二手商品档案管理模块2.3 商品预约管理模块2.4 商品预定管理模块2.5 商品留言板管理模块2.6 商品资讯管理模块 三、实体类设计3.1 用户表3.2 二手商品表3.3 商品预约表3.4 商品预定表3.5 留言表3.6…

Vue 中 slot 是什么?作用?分类?如何实现?

结论先行&#xff1a; slot 插槽&#xff0c;是子组件提供给父组件使用的一个占位符&#xff0c;父组件可以在这个占位符中填充任何模板代码。主要作用就是更好的拓展和定制化组件&#xff0c;例如弹窗组件、表格组件等。分为默认插槽、具名插槽和作用域插槽。 其中前两个都是…

代码随想录算法训练营第五十一天|309. 买卖股票的最佳时机含冷冻期、714. 买卖股票的最佳时机含手续费

第九章 动态规划part12 309. 买卖股票的最佳时机含冷冻期 给定一个整数数组prices&#xff0c;其中第 prices[i] 表示第 i 天的股票价格 。​ 设计一个算法计算出最大利润。在满足以下约束条件下&#xff0c;你可以尽可能地完成更多的交易&#xff08;多次买卖一支股票&…

Uniapp-小程序自定义导航栏

一、项目背景 制作小程序页面时候发现原生导航栏有一定的高度是没有背景渲染的会出现这种情况 但是我们需要的是 二、原因 小程序的原生导航栏存在。一般可以使用 纯色填充顶部栏 可以直接使用navigationBarBackgroundColor完成 在style中添加 "navigationBarBackgrou…

JJJ:python学习笔记

p4 没有编译的过程 源码和输入得到输出 静态语言&#xff1a;编译型 脚本语言&#xff1a;解释型 p5 又叫做胶水语言 p7 p8 p10

91.移动零(力扣)

问题描述 代码解决以及思想 class Solution { public:void moveZeroes(vector<int>& nums) {int left 0; // 左指针&#xff0c;用于指向当前非零元素应该放置的位置int right 0; // 右指针&#xff0c;用于遍历数组int len nums.size(); // 数组长度while …

Postman内置动态参数以及自定义的动态参数

近期在复习Postman的基础知识&#xff0c;在小破站上跟着百里老师系统复习了一遍&#xff0c;也做了一些笔记&#xff0c;希望可以给大家一点点启发。 一&#xff09;内置动态参数 {{$timestamp}} 生成当前时间的时间戳{{$randomInt}} 生成0-1000之间的随机数{{$guid}} 生成随…

IDEA没有Add Framework Support解决办法

点击File—>Settings 点击第一个设置快捷键 点击apply和ok即可 我们要点击一下项目&#xff0c;再按快捷键ctrlk 即可

javaweb---maventomcat使用教程

文章目录 今日内容0 复习昨日1 Maven1.0 引言1.1 介绍1.2 下载1.3 安装1.3.1 解压1.3.2 配置环境变量1.3.3 测试 1.4 仓库1.5 Maven配置1.5.1 修改仓库位置1.5.2 设置镜像 2 IDEA - MAVEN2.1 idea关联maven2.2 创建java项目2.3 java项目结构2.4 pom2.5 导入依赖2.5.1 查找依赖2…

氢原子波函数等概率面的绘制

氢原子波函数等概率面的绘制 归一化后的氢原子波函数

c语言:如何打印杨辉三角形。

题目&#xff1a;打印杨辉三角形 如&#xff1a; 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 思路和代码&#xff1a; //由规律不难得出&#xff0c;每行首个数字和最后最后一个数字都为1&#xff0c;其余数字是这列的上一个数字和前一个数字的和组成&#xff0c;由此推出代码 #de…