spring boot 常见问题

什么是 Spring Boot?

简单来说,spring boot 底层就是:spring + spring mvc + tomcat + 其他框架 starter;

spring boot 依靠 spring 的核心功能,减少了项目开发中繁杂的依赖管理和配置文件管理;

将整合其他框架所需的样板代码及配置文件提前准备好,想要使用哪个框架,直接在依赖中引入该框架的 starter 就行了;

(1)依赖管理:spring boot 将市面上常用的开源框架和中间件的依赖都整合成了 starter 依赖,想要整合哪个开源框架,直接在 pom 文件中引入该框架的 starter 依赖即可;

(2)配置文件管理:spring boot 使用 .properties、.yml 配置文件为所有引入的框架或中间件提供配置项的管理;

Spring Boot 的核心注解是哪个?它主要由哪几个注解组成的?

@SpringBootApplication,Spring Boot 的核心注解,主要组合包含了以下 3 个注解:

@SpringBootConfiguration:其实底层就是一个@Configuration 注解,就是标注该启动类是 spring ioc 容器中的一个配置类;

@EnableAutoConfiguration:该注解的作用是使用@Import 注解引入了两个类,AutoConfigurationImportSelector 和 AutoConfigurationPackages.Registrar;

该注解的作用是,打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据源自动配置功能: @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class });

@ComponentScan:包扫描注解;

AutoConfigurationPackages.Registrar 的作用:告诉 spring boot,基包是哪一个;

该类的源码:

AutoConfigurationImportSelector 的作用:加载 spring boot 自己写的配置类;

该类实现的接口:AutoConfigurationImportSelector -> DeferredImportSelector -> ImportSelector

首先说明 ImportSelector 接口的作用;

可以简单理解为,这个接口和 @Import + @Configuration 两个注解搭配使用的;

_ImportSelector 接口有一个方法_String[] selectImports(AnnotationMetadata importingClassMetadata);

这个方法的作用是,如果你定义了一个接口 InterfaceA,又写了两个实现类 ClassB、ClassC;

如果 ClassB、ClassC 上没加 @Component 等 spring 注解,你又想要把这个类加入到 spring ioc 容器中;

可以使用这个接口方法实现;(具体的代码示例就不写了…)

回到 spring boot 中来,让我们看看 AutoConfigurationImportSelector 类使用 selectImports 方法将哪些类加入到了 ioc 容器中;

源码中最主要的一句代码:

这个就是在加载 spring.factories 文件中带有 @EnableAutoConfiguration 注解所有配置的值,也就是下面的东西:

这么多都是些啥?

这些就是 spring boot 全场景下的配置类;

为什么 spring boot 只需要引入 spring-boot-starter-web 就可以使用 spring mvc + tomcat 的功能了,完全不需要写任何配置文件,或是创建 DispatcherServlet 对象;

为什么我们只需要在 yml 配置文件中添加数据库连接信息,就可以直接连接数据库了,也没有写过 Class.forName(“com.mysql.jdbc.Driver”) 相关的代码;

就是因为 spring boot 已经将市面上大部分的开源框架或中间件的全场景配置都配置好了,并将配置类的路径名写到了 spring.factories 这个文件中;

当 spring boot 启动的时候就会加载这个文件,并将程序员想要添加的配置类加载到了 ioc 容器中;

Spring Boot 自动配置原理是什么?

注解 @EnableAutoConfiguration, @Configuration, @ConditionalOnClass 就是自动配置的核心;

@EnableAutoConfiguration 给容器导入 META-INF/spring.factories 里定义的自动配置类,筛选有效的自动配置类;

每一个自动配置类结合对应的 xxxProperties.java 读取配置文件进行自动配置功能;

Spring Boot 启动流程

既然是 Spring Boot 的启动流程,那么入口必然是启动类中的 run 方法:

1、启动 spring boot 启动类中的 main 方法;

2、使用启动类的 class 对象,创建一个 SpringApplication 对象;

在这个类的构造函数中,会执行 _getSpringFactoriesInstances 这个方法,从 META-INF/spring.factories 文件中加载_ContextInitializer 初始化器和 Listener 监听器;

将加载到的类信息放入缓存中,等着 ioc 容器启动的时候加载使用;

3、然后执行 SpringApplication 对象的 run 方法;

该方法中会执行两个很重要的方法,prepareContext 和 refreshContext 方法;

prepareContext 将启动类的 beanDefinition 注册到 register 当中,方便后续解析;

refreshContext 就是调用执行 spring ioc 容器的刷新方法;

4、开始执行 ioc 容器的 refresh 方法;

其中会执行 invokeBeanFactoryPostProcessor 方法,这里面会执行一个 ConfigurationClassPostProcessor 配置类解析的后置处理器;

ConfigurationClassPostProcessor 实现了两个接口,BeanFactoryPostProcessor 和 BeanDefinitionRegistryPostProcessor;

ConfigurationClassPostProcessor 会解析启动类上的注解,并执行由 @Import 注解注入的 AutoConfigurationImportSelector 类的 process 方法;

5、process 的方法中,会加载 spring.factories 文件中标注了 @EnableAutoConfiguration 注解的自动装配配置类;

这些配置类中会用 @Condition 条件注解,在 ioc 容器或引入的 jar 包中或配置文件中比对条件,来决定是否加载对应的 bean;

6、process 方法执行完毕后,剩下的就是 spring ioc 容器的启动流程;

7、在 onrefresh() 方法中会执行 createWebServer() 方法,创建 Web 容器,也就是启动 tomcat;

8、tomcat 启动后执行 Servlet 的生命周期,也就是执行 DispatcherServlet 的 initStrategies 初始化方法;

在 initStrategies 方法中会从 spring ioc 容器中初始化 spring mvc 运行所需的九大组件;

handlerMapping 控制器;handlerAdapter 适配器;handlerExceptionResolver 异常解析器;viewResolver 视图解析器;

9、执行后续的 spring ioc 容器的启动流程

Original: https://www.cnblogs.com/whatzyt/p/16096628.html
Author: whatzyt
Title: spring boot 常见问题

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/571726/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 访问Github速度很慢以及解决方法(系统通用)

    原因分析1,CDN,Content Distribute Network,可以直译成内容分发网络,CDN解决的是如何将数据快速可靠从源站传递到用户的问题。用户获取数据时,不需要直接…

    Java 2023年6月14日
    099
  • Nacos如何实现服务自动注册

    1. 背景 接着上次的说,Nacos问题的分析。这次就来分享一下自己的分析方法。以及如何利用Spring事件完成服务注册。 2. 分析一下 2.1 问题分析过程 问题是这样的,我以…

    Java 2023年6月15日
    0107
  • java 递归转非递归(树形转非树形)

    接着上一篇讲,在上一篇我们已经将数据通过递归转成了树形结构。 如何将树形结构转非树形结构?(仍然按照树形层级关系进行平铺显示) 如何将递归函数转成迭代函数? 查看代码 [{ nam…

    Java 2023年5月29日
    0138
  • 利用Github Action实现Tornadofx/JavaFx打包

    原文地址: 利用Github Action实现Tornadofx/JavaFx打包 – Stars-One的杂货小窝 最近开了个新项目stars-one/xtool: …

    Java 2023年6月14日
    0109
  • 读取resources下的资源

    这里我通过一个普通的SpringBoot项目进行测试,当然其他项目也都是通用的。 将其中的Test修改为你的类名即可: java;gutter:true; import lombo…

    Java 2023年6月6日
    0100
  • Guava 内存缓存的使用

    一、概述 guava⽬前有三种刷新本地缓存的机制: expireAfterAccess:当缓存项在指定的时间段内没有被读或写就会被回收。 expireAfterWrite:当缓存项…

    Java 2023年6月7日
    086
  • 面向对象编程,不美了么?

    “我是旧时代的残党,新时代没有承载我的船。” 如果面向对象编程是一个人,我猜他自己在不断被非议的今天,一定会这样感慨。 说实话,我用面向对象方式编程已经十几…

    Java 2023年6月7日
    091
  • 微服务SpringCloud之GateWay服务化和过滤器

    Spring Cloud Gateway 提供了一种默认转发的能力,只要将 Spring Cloud Gateway 注册到服务中心,Spring Cloud Gateway 默认…

    Java 2023年5月30日
    0100
  • JVM的垃圾回收机制

    前言:建议先了解JVM的内存结构才能对垃圾回收有更深的理解,可以移步JVM内存结构 我们都知道:java最大的特点就是实现自动内存管理(自动分配对象,自动垃圾回收),接下来我们就看…

    Java 2023年6月7日
    0101
  • 03-Eureka注册中心

    1、介绍 2、快速开始 2.1 pom文件依赖

    Java 2023年6月7日
    081
  • Java链接Mysql数据库整理,尽管很简单,但还是分享出来,希望对那些初级朋友有所帮助!!!

    Java MySQL 连接 Java MySQL 连接本章节我们为大家介绍 Java 如何使用 使用 JDBC 连接 MySQL 数据库。Java 连接 MySQL 需要驱动包,最…

    Java 2023年6月16日
    068
  • Java 求两区间的交集,并返回交集区间

    java;gutter:true; public double[] confMatrix(double[] arr1, double[] arr2){ double[] con =…

    Java 2023年5月29日
    0103
  • Vuex 简单使用

    官网:https://vuex.vuejs.org/zh/ 参考文章:https://www.cnblogs.com/chinabin1993/p/9848720.html Vue…

    Java 2023年6月13日
    070
  • 【IoT】MQTT Client软件-MQTTBox

    MQTTBox0.2.1下载:https://github.com/workswithweb/MQTTBox 环境对齐 PS E:\2000_AIoT\MQTTBox-master…

    Java 2023年5月29日
    082
  • 【软件构造】Java中的接口Interface

    【软件构造】Java中的接口Interface 1.前言 在Lab2中,要求通过Graph接口达到不同种类的实现目标,实验过程中也多次用到了java接口这一概念,编程时涉及了很多需…

    Java 2023年6月5日
    094
  • 黑喵桌面音乐播放器汉化版

    安装方法:解压CharaColle,运行Regpatch。exe 注册游戏(XP 系统需要装.net framework 2.0)即可启动游戏。启动比较慢,请大家耐心下 使用说明:…

    Java 2023年5月29日
    079
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球