1、SpringBoot启动流程

SpringBoot自动配置原理 - 图1

2、SpringBoot原理

2.1 流程图

  • SpringBoot自动配置原理 - 图2

    2.2 具体流程分析

  • SpringBootConfiguration

  • Configuration
  • EnableAutoConfiguration
    • 这个注解的作用是告诉SpringBoot开启自动配置功能,这样就减少了我们的配置
      • AutoConfigurationPackage
        • 观察其内部实现,内部是采用了@Import,来给容器导入一个Registrar组件
        • 通过源码跟踪,我们知道,程序运行到这里,会去加载启动类所在包下面的所有类
        • 就是为什么,默认情况下,我们要求定义的类,比如controller,service必须在启动类的同级目录或子级目录的原因
      • Import(AutoConfigurationImportSelector.class)
        • 发现默认加载了好多的自动配置类,这些自动配置类,会自动给我们加载每个场景所需的所有组件,并配置好这些组件,这样就省去了很多的配置
  • 深入理解SpringBoot启动机制(starter机制)
    • @Configuration注解的类可以看作是能生产让Spring IoC容器管理的Bean实例的工厂。
    • @Bean注解告诉Spring,一个带有@Bean的注解方法将返回一个对象,该对象应该被注册到spring容器中。
  • DataSourceAutoConfiguration
    • EnableConfigurationProperties
      • @EnableConfigurationProperties注解的作用是使@ConfigurationProperties注解生效。如果只配置@ConfigurationProperties注解,在spring容器中是获取不到yml或者properties配置文件转化的bean的.
    • ConfigurationProperties
      • @ConfigurationProperties注解的作用是把yml或者properties配置文件转化为bean。
  • Bean的发现
    • 实际上重要的只有三个Annotation:
      • @Configuration(@SpringBootConfiguration里面还是应用了@Configuration)
        • @Configuration的作用上面我们已经知道了,被注解的类将成为一个bean配置类
      • _@_ComponentScan
        • @ComponentScan的作用就是自动扫描并加载符合条件的组件,比如@Component和@Repository等,最终将这些bean定义加载到spring容器中
      • @EnableAutoConfiguration
        • @AutoConfigurationPackage
          • @AutoConfigurationPackage的作用就是自动配置的包
        • _@_Import
          • @Import导入需要自动配置的组件。
    • 每个xxxAutoConfiguration都是一个基于java的bean配置类。实际上,这些xxxAutoConfiguratio不是所有都会被加载,会根据xxxAutoConfiguration上的@ConditionalOnClass等条件判断是否加载;通过反射机制将spring.factories中@Configuration类实例化为对应的java实列
  • Bean 加载
    • 如果要让一个普通类交给Spring容器管理,通常有以下方法:
    • springboot中使用了_@_Import 方法
    • @EnableAutoConfiguration注解中使用了@Import({AutoConfigurationImportSelector.class})注解,AutoConfigurationImportSelector实现了DeferredImportSelector接口,
    • DeferredImportSelector接口继承了ImportSelector接口,ImportSelector接口只有一个selectImports方法。
    • selectImports方法返回一组bean,@EnableAutoConfiguration注解借助@Import注解将这组bean注入到spring容器中,springboot正式通过这种机制来完成bean的注入的。

      3、总结

      ```properties 1.@SpringbootAplication底层可拆分为三个注解@SpringBootConfiguration、@EnableAutoConfiguration和@ComponentScan 2.@SpringBootConfiguration是对spring注解@Configuration的包装 3.@ComponentScan定义 了默认的扫包范围为当前启动类所在包下的所有类 4.@EnableAutoConfiguration中主要引入了AutoConfigurationImportSelector这个类选择器 5.AutoConfigurationImportSelector中将org.springframework.boot.autoconfigure这个依赖jar中的spring.factories文件中的类全部加载 6.spring.factories中定义了很多配置类,其中包括DispatcherServletAutoConfiguration(springMVC核心类)和ServletWebServerFactoryAutoConfiguration(容器类) 7.ServletWebServerFactoryAutoConfiguration中 通过@Import将三种web容器注入IOC:EmbeddedTomcat、EmbeddedJetty和EmbeddedUndertow 8.以默认的tomcat为例,IOC:EmbeddedTomcat中通过@Bean的方式将TomcatServletWebServerFactory注入IOC 9.TomcatServletWebServerFactory的getWebServer会创建tomcat服务器,并将本地class文件交由其运行管理

启动运行流程 1.springboot启动时,会先创建sprinApplication对象,再执行其run方法 2.创建springApplication对象时会先判断当前启动时哪一类型的WebApplicationType 3.通过setInitializers和setListeners会将所有jar中/resources/META-INF/下的spring.factories文件中的类注入IOC 4.执行run方法时,会开启计时 5.获取所有的启动listener 6.将环境加载 7.打印轮播图 8.创建springboot的上下文对象 9.装配上下文 10.刷新上下文(和spring注解方式启动原理一致) 11.刷新之后的后续操作(扩展) 12.发布订阅的方式广播通知listener,context要启动了 13.发布订阅的方式广播通知listener,context已经启动 ``` 年强:
年强 08:48:32
SpringBoot:自动化配置原理

年强 08:49:58
‘SpringCloud组件:Ribbon原理, Feign原理

年强 08:50:53
分布式事务:2PC、TCC、Seata-AT、MQ最终一致性

年强:
分布式事务口诀:
多服务多数据源
服务间存在 增删改的远程调用

年强:
作用:使用@Import导入的类会被Spring加载到IOC容器中
@Import提供4中用法:
1. 导入Bean
2. 导入配置类
3. 导入 ImportSelector 实现类。一般用于加载配置文件中的类
4. 导入 ImportBeanDefinitionRegistrar 实现类

年强:
//1、 User 创建Bean存到 IOC容器, name=类名全路径 com.itheima.sh.pojo.User
//@Import(User.class)

//2、导入配置类:MyConfig Bean 存到IOC容器 name=MyConfig类名全路径, User Bean存在 name=方法名
//@Import(MyConfig.class)

//3、导入ImportSelector选择器,按照返回的数组类创建Bean, name=类的全路径, @bean 创建Bean name=默认是方法名
// 批量导入Bean对象 *
//@Import(MyImportSelector.class)
//extends SpringBootServletInitializer
//4、导入ImportBeanDefinitionRegistrar实现类, 按照registerBeanDefinitions方法注入Bean对象
@Import(MyImportBeanDefinitionRegistrar.class)

年强:
Spring常见的注解有哪些?

年强:
SpringMVC常见的注解有哪些?

年强:
SpringBoot常见的注解有哪些?

年强:
5ed95e798fdc57848eb44ed15caf942.png

年强:
/*
@Description: 约定优于配置优于编码(JavaConfig配置类)
@Version: V1.0
1、SpringBoot如何获取到所有的自动化配置? 实例化?
类 + 方法:META-INF/spring.factories 配置文件中
2、这些自动化配置的类是否会全部生效? 为什么?
不会全部生效,取决于 @ConditionalOnXXX 条件注解,如果全部满足条件,则会初始化bean到IOC容器中
3、如果自动化配置的类生效了,默认的配置是什么? 怎么获取的?
配置属性对象的默认值,并且也提供了自定义配置,通过application.yml配置文件中只需要按照预先约定进行配置即可
*/

年强:
SpringBoot 2.3.10 127个 XXAutoConfiguration 自动化配置类需要初始化,但是需要满足条件才可以被初始化

年强:
42a6a63b74acac54f1cdd8b33daff9a.png

年强:
@ConditionalOnClass(RedisOperations.class)
在当前项目存在 RedisOperations.class 字节码时,当前配置类生效
如果想要在业务中 注入redisTemplate,
@ConditionalOnMissingBean(name = “redisTemplate”)
在当前IOC容器中不存在 redisTemplate 名称的Bean时,当前配置类中的 redisTemplate 方法才会被执行

年强:
@EnableConfigurationProperties(RedisProperties.class)
绑定配置文件中的属性到Bean对象, 存到IOC容器中,初始化过程需要用到配置信息

年强:
约定值: RedisProperties写死的值
@ConfigurationProperties(prefix = “spring.redis”) 可以通过配置文件
spring.redis.port = 9999
读取后通过 setPort(9999) 设置到port属性,就会将默认值覆盖

年强:
/*
@Description: 约定优于配置优于编码(JavaConfig配置类)
@Version: V1.0
1、SpringBoot如何获取到所有的自动化配置? 实例化?
类 + 方法:META-INF/spring.factories 配置文件中
2、这些自动化配置的类是否会全部生效? 为什么?
不会全部生效,取决于在类和方法上 @ConditionalOnXXX 条件注解,如果全部满足条件,则会初始化bean到IOC容器中
3、如果自动化配置的类生效了,默认的配置是什么? 怎么获取的?
配置属性对象的默认值,并且也提供了自定义配置,通过application.yml配置文件中只需要按照预先约定进行配置即可
约定值: RedisProperties写死的值port=6379
@ConfigurationProperties(prefix = “spring.redis”) 可以通过配置文件
spring.redis.port = 9999
读取后通过 setPort(9999) 设置到port属性,就会将默认值覆盖
*/

年强:
1、找到所有的自动化配置类
2、按照条件进行初始化自动化配置类
3、加载默认配置,在初始化Bean时使用

开发人员使用步骤总结:
● 引入场景依赖
● 查看自动配置了哪些(选做)
○ 自己分析,引入场景对应的自动配置一般都生效了
○ 配置文件中debug=true开启自动配置报告。Negative(不生效)\Positive(生效)
● 自己分析是否需要修改
○ 参照文档修改配置项,xxxxProperties绑定了配置文件的哪些。
○ 自定义加入或者替换组件,@Bean、@Component等