SpringBoot原理

SpringBoot自动配置原理

  • SpringBoot先加载所有的自动配置类 xxxAutoConfiguration
  • 每个自动;配置类按照条件进行生效,默认
    1. @SpringBootApplication //合成注解
    2. public class SpringBootTestApplicaton{
    3. public static void main(String[] args){
    4. SpringApplicaton.run(SpringBootTestApplicaton.class,args);
    5. }
    6. }

SpringBoot启动过程

  1. @SpringBootApplication
  2. public class SpringBootTestApplicaton{
  3. public static void main(String[] args){
  4. SpringApplicaton.run(SpringBootTestApplicaton.class,args);
  5. }
  6. }
  • 创建SpringApplication
    • 保存了一些信息
    • 判断当前应用的类型,ClassUtil Servlet
    • bootstrappers;初始启动引导器(List):去spring.factorles文件中找org.springframework.boot.Bootstrapper
    • 找ApplicationContextInitialize;应用初始化器:去spring.factorice找ApplicationContextInitializer
      • List> initializers
    • 找ApplicationListerner;应用监听器:去spring.factiorice找ApplicationListerner
      • List> listeners
  • 运行SpirngApplication
    • StopWatch(停止监视)
    • 记录应用的启动时间
    • 创建引导上下文(Context环境)createBootstrapContext()
      • 获取到所有值钱的bootstrappers挨个执行,initialize()来完成对引导启动器上下文环境设置
    • 让当前应用进入headless(无领导)模式。java.awt.headless
    • 获取所有RUnListener(运行监听器)【为了方便所有Listener进行事件感知】
      • getSrpingFactoriesInstances去spring.factories找SpirngApplicationRunListener
    • 遍历SpringApplicationRunListener调用Starting方法:
      • 相当于通知所有感兴趣系统正在启动过程的人,项目正在starting
    • 保存命令行参数:ApplicationArguments
    • 准备环境prepareEnvironment();
      • 返回或者创建基础环境信息对象:StandardServletEnvironment
      • 配置环境信息对象
        • 读取所有的配置源的配置属性值
      • 绑定环境信息
      • 监听器调用listener,environmentPrepared();通知所有监听器当前环境准备完成
    • 创建IOC容器(createApplicationContext())
      • 根据项目类型(Servlet)创建容器
      • 当前会创建AnnotationConfigServletWebServerApplicationContext
    • 准备ApplicationCOntext IOC容器的基本信息 prepareContext()
      • 保存环境信息
      • IOC容器的后置处理流程
      • 应用初始化器:applyInitializes
        • 遍历所有的ApplicationCOntextInitializer 调用Initialize来对ioc容器进行初始化扩展功能
        • 遍历所有的listerner调用contextPrepared。EventpublishRunListener;通知所有监听器contextPrepared
      • 所有的监听器调用contextloaded。通知所有的监听器contextloaded
    • 刷新IOC容器 refreshContext
      • 创建容器中的所有组件(Spring注解)
    • 容器刷新完成后工作?afterRefresh
    • 所有监听器调用listeners.started(context);通知所有监听器starter
    • 调用所有runners;callRUnners()
      • 获取容器中的ApplicationRunner
      • 获取容器中的CommandLineRUnner
      • 合并所有的runner并且按照@Order进行排序
      • 变量所有的runner。调用run方法
    • 如果以上有异常
      • 调用Listener的failed
    • 调用所有的监听器running方法 listeners.running(context);通知所有监听器running
    • running如果有问题件 继续通知failed 调用所有的Listener的failed 通知所有的监听器failed

注解

@Configuration

  • 类型:类注解
  • 作用:告诉springboot这是一个配置类 == 配置文件
  • 属性:
    • proxyBeanMethods:是否为代理bean的方法
      • Full模式 可选值false:
      • Lite模式 默认ture:(代理对象调用方法)无论调用多少次此方法都是之前注册到容器中的单实例对象
  • 说明:
    1. @Configuration
    2. public class MyConfig{
    3. @Bean //给容器中添加组件,以方法名为组件id,返回类型就是组件的类型,返回的值就是组件在容器中的实例
    4. public User user01(){return new User("zhangsan",18);}
    5. }

@Conditional

  • 类型:方法注解
  • 作用:条件装配
  • 属性:
  • 说明:
    1. @Configuration
    2. public class MyConfig{
    3. @ConditionalOnBean(name = "user") //判断容器中是否包含user 如果存在则想容器中添加user01
    4. @Bean //给容器中添加组件,以方法名为组件id,返回类型就是组件的类型,返回的值就是组件在容器中的实例
    5. public User user01(){return new User("zhangsan",18);}
    6. }

@ImportResource

  • 类型:方法注解
  • 作用:导入配置资源
  • 属性:`classpath:配置文件名 导入指定配置文件
  • 说明:
    1. @Configuration
    2. @ImportResource("classpath:beans.xml")
    3. public class MyConfig{
    4. @ConditionalOnBean(name = "user") //判断容器中是否包含user 如果存在则想容器中添加user01
    5. @Bean //给容器中添加组件,以方法名为组件id,返回类型就是组件的类型,返回的值就是组件在容器中的实例
    6. public User user01(){return new User("zhangsan",18);}
    7. }

@ConfigurationProperties

  • 类型:类注解
  • 作用:配置绑定
  • 属性:
    • prefix :前缀

  • 说明:只有在容器中的组件才能使用
    1. @Component
    2. @ConfigurationProperties(prefix = "mycar")
    3. public class Car{
    4. private String a;
    5. private Integer b;
    6. }
    1. mycar.a=1
    2. mycar.b=2

@EnableConfigurationProperties

  • 类型:类注解
  • 作用:开启功能和@Componet
  • 属性:包名.class
  • 说明:只有在容器中的组件才能使用 用于第三方包配置绑定 ```java @Configuration @EnableConfigurationProperties(Car.class) public class MyConfig{ @Bean //给容器中添加组件,以方法名为组件id,返回类型就是组件的类型,返回的值就是组件在容器中的实例 public User user01(){return new User(“zhangsan”,18);} }

@ConfigurationProperties(prefix = “mycar”) public class Car{ private String a; private Integer b; }

  1. ```properties
  2. mycar.a=1
  3. mycar.b=2

@SpringBootApplication

组合注解

  1. @SpringBootConfiguration
  2. @EnableAutoConfiguration
  3. @ComponentScan //扫描指定包 spring提供的

@SpringBootConfiguration

  • 类型:类注解
  • 作用:告诉springboot这是一个配置类 == 配置文件
  • 属性:
  • 说明:继承与@Configuration
  1. //标注配置类
  2. @Configuration

@EnableAutoConfiguration

EnableAutoConfiguration实现的关键在于引入了AutoConfigurationImportSelector
其核心逻辑为selectImports方法,逻辑大致如下:

  1. 从配置文件META-INF/spring.factories加载所有可能用到的自动配置类;
  2. 去重,并将exclude和excludeName属性携带的类排除;
  3. 过滤,将满足条件(@Conditional)的自动配置类返回;

开启自动配置

  1. @AutoConfigurationPackage
  2. @Import(AutoConfigurationImprotSelector.class)
  3. public @interface EnableAutoConfiguration {}

@AutoConfigurationPackage

自动配置包

  1. @Import(AutoConfigurationPackages.Registrar.class) //将主程序包下的所有组件导入 批量注册
  2. public @interface AutoConfigurationPackage {}
  3. //利用Registrar给容器中导入一系列组件
  4. //将指定包下的所有组件导入进来 MainApplication所在包下