面试问题浓缩总结 面试问题浓缩总结
  • Go
  • Java
  • C/C++
  • JavaScript/HTML
  • MySQL
  • Redis
  • MongoDB
  • 操作系统
  • 计算机网络
  • spring全家桶
  • mybatis
  • 中间件
  • 软件相关
  • 系统相关
  • 算法
  • 数据结构
  • 设计模式
  • CMU硕士经典100题
  • 剑指offer
  • 重点手撕代码
  • 程序员面试金典
  • 3月
  • 4月
  • 智力题
  • 业务问题
  • 一些技术
  • 安全相关
APP下载 (opens new window)
GitHub (opens new window)
  • Go
  • Java
  • C/C++
  • JavaScript/HTML
  • MySQL
  • Redis
  • MongoDB
  • 操作系统
  • 计算机网络
  • spring全家桶
  • mybatis
  • 中间件
  • 软件相关
  • 系统相关
  • 算法
  • 数据结构
  • 设计模式
  • CMU硕士经典100题
  • 剑指offer
  • 重点手撕代码
  • 程序员面试金典
  • 3月
  • 4月
  • 智力题
  • 业务问题
  • 一些技术
  • 安全相关
APP下载 (opens new window)
GitHub (opens new window)
  • spring全家桶

    • IOC
    • AOP
    • spring MVC
    • springSecurity
    • 面试问题
    • 循环依赖
    • 事务
    • 启动流程和配置
      • springboot启动
        • springboot启动类上的注解
        • spring boot启动流程
        • SpringApplication 实例的初始化
      • springboot配置文件
    • 注解相关
  • mybatis

  • 中间件

  • 框架
  • spring全家桶
小游
2021-04-02

启动流程和配置

# springboot启动

# springboot启动类上的注解

一般来说我们的启动类需要有下面这几个注解

# @SpringBootApplication

这个是一个非常核心的注解,我们使用springboot项目一般都是只需要开启这个就可以了,这个是一个组合注解,里面有三个非常重要的注解

  • @Configuration(@SpringBootConfiguration点开查看发现里面还是应用了@Configuration)
  • @EnableAutoConfiguration
  • @ComponentScan

@Configuration这个注解其实就是把我们的配置类都注入到IOC容器中,一般情况下,我们有两种方式来配置

第一种是在xml文件中配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
       default-lazy-init="true">
    <!--bean定义-->
     <bean id="mockService" class="..MockServiceImpl">
	     ...
	 </bean>
</beans>
1
2
3
4
5
6
7
8
9
10

第二种我们可以直接加上@configuration注解

@Configuration 
public class MockConfiguration{     
	//bean定义
	@Bean
     public MockService mockService(){
         return new MockServiceImpl();
     }
}
1
2
3
4
5
6
7
8

任何一个标注了@Bean的方法,其返回值将作为一个bean定义注册到Spring的IoC容器,方法名将默认成该bean定义的id

@ComponentScan下面有解释,这里就不多说了

@EnableAutoConfiguration下面也有解释

# @ComponentScan

@ComponentScan这个注解在Spring中很重要,它对应XML配置中的元素,@ComponentScan的功能其实就是自动扫描并加载符合条件的组件(比如@Component和@Repository等)或者bean定义,最终将这些bean定义加载到IoC容器中。

我们可以通过basePackages等属性来细粒度的定制@ComponentScan自动扫描的范围,如果不指定,则默认Spring框架实现会从声明@ComponentScan所在类的package进行扫描。

注:所以SpringBoot的启动类最好是放在root package下,因为默认不指定basePackages。

# @EnableAutoConfiguration 注解

大家是否还记得Spring框架提供的各种名字为@Enable开头的Annotation定义?比如@EnableScheduling、@EnableCaching、@EnableMBeanExport等,@EnableAutoConfiguration的理念和做事方式其实一脉相承,简单概括一下就是,借助@Import的支持,收集和注册特定场景相关的bean定义。

  • @EnableScheduling是通过@Import将Spring调度框架相关的bean定义都加载到IoC容器。
  • @EnableMBeanExport是通过@Import将JMX相关的bean定义加载到IoC容器。

而@EnableAutoConfiguration也是借助@Import的帮助,将所有符合自动配置条件的bean定义加载到IoC容器

@EnableAutoConfiguration作为一个复合Annotation,其自身定义关键信息如下:

@SuppressWarnings("deprecation")
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
    ...
}
1
2
3
4
5
6
7
8
9
10

借助于Spring框架原有的一个工具类:SpringFactoriesLoader的支持,@EnableAutoConfiguration可以智能的自动配置

img

SpringFactoriesLoader属于Spring框架私有的一种扩展方案,其主要功能就是从指定的配置文件META-INF/spring.factories加载配置。

这个其实就是那个springboot的自动装配了,这个单独放到一个章节来进行讲解

# @SpringBootConfiguration

@SpringBootConfiguration继承自@Configuration,二者功能也一致,标注当前类是配置类, 并会将当前类内声明的一个或多个以@Bean注解标记的方法的实例纳入到spring容器中,并且实例名就是方法名。

# @Inherited 注解

这个是元注解

# @Documented 注解

Documented注解表明这个注释是由 javadoc记录的,在默认情况下也有类似的记录工具。 如果一个类型声明被注释了文档化,它的注释成为公共API的一部分。

# @Retention() 注解

RetentionPolicy这个枚举类型的常量描述保留注释的各种策略,它们与元注释(@Retention)一起指定注释要保留多长时间

参考:

  • SpringBoot 启动类 @SpringBootApplication 注解 以及执行流程_殇莫忆的博客-CSDN博客 (opens new window)
  • spring boot(二):启动原理解析 - 平凡希 - 博客园 (cnblogs.com) (opens new window)

# spring boot启动流程

preview

spring boot的run方法如下:

image.png

各个流程对应如下

image.png

我们将各步骤总结精炼如下:

  1. 通过 SpringFactoriesLoader 加载 META-INF/spring.factories 文件,获取并创建 SpringApplicationRunListener 对象
  2. 然后由 SpringApplicationRunListener 来发出 starting 消息
  3. 创建参数,并配置当前 SpringBoot 应用将要使用的 Environment
  4. 完成之后,依然由 SpringApplicationRunListener 来发出 environmentPrepared 消息
  5. 创建 ApplicationContext
  6. 初始化 ApplicationContext,并设置 Environment,加载相关配置等
  7. 由 SpringApplicationRunListener 来发出 contextPrepared 消息,告知SpringBoot 应用使用的 ApplicationContext 已准备OK
  8. 将各种 beans 装载入 ApplicationContext,继续由 SpringApplicationRunListener 来发出 contextLoaded 消息,告知 SpringBoot 应用使用的 ApplicationContext 已装填OK
  9. refresh ApplicationContext,完成IoC容器可用的最后一步
  10. 由 SpringApplicationRunListener 来发出 started 消息
  11. 完成最终的程序的启动
  12. 由 SpringApplicationRunListener 来发出 running 消息,告知程序已运行起来了

至此,全流程结束!

# SpringApplication 实例的初始化

关键部分如下

image.png

  • ① 推断应用的类型:创建的是 REACTIVE应用、SERVLET应用、NONE 三种中的某一种

    image.png

  • ② 使用 SpringFactoriesLoader查找并加载 classpath下 META-INF/spring.factories文件中所有可用的 ApplicationContextInitializer

    image.png

  • ③ 使用 SpringFactoriesLoader查找并加载 classpath下 META-INF/spring.factories文件中的所有可用的 ApplicationListener

    image.png

  • ④ 推断并设置 main方法的定义类

    image.png

参考:

SpringBoot 应用程序启动过程探秘 (juejin.cn) (opens new window)

# springboot配置文件

一般来说有YAML和Properties这两种方式,默认推荐使用yaml的方式

编辑 (opens new window)
上次更新: 2021/04/07, 21:26:09
事务
注解相关

← 事务 注解相关→

Theme by Vdoing | Copyright © 2021-2021 小游
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式