• 【SpringBoot】SpringBoot程序启动说明


    基本的SpringBoot的应用程序,有两个重要元素:

    • 注解:@SpringBootApplication
    • 启动方法:SpringApplication.run(FirstBootApplication.class, args) ;

     1、@SpringBootApplication注解

     1 @Target(ElementType.TYPE)
     2 @Retention(RetentionPolicy.RUNTIME)
     3 @Documented
     4 @Inherited
     5 @SpringBootConfiguration
     6 @EnableAutoConfiguration
     7 @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
     8         @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
     9 public @interface SpringBootApplication {
    10 
    11     @AliasFor(annotation = EnableAutoConfiguration.class)
    12     Class<?>[] exclude() default {};
    13 
    14     @AliasFor(annotation = EnableAutoConfiguration.class)
    15     String[] excludeName() default {};
    16 
    17     @AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
    18     String[] scanBasePackages() default {};
    19     
    20     @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
    21     Class<?>[] scanBasePackageClasses() default {};
    22 
    23     @AliasFor(annotation = ComponentScan.class, attribute = "nameGenerator")
    24     Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
    25 
    26     
    27     @AliasFor(annotation = Configuration.class)
    28     boolean proxyBeanMethods() default true;
    29 }
    • @SpringBootConfiguration 配置类SpringBoot社区推荐基于JavaConfig配置方式定义Bean
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Configuration
    public @interface SpringBootConfiguration {
    • @EnableAutoConfigurationSpringBoot实现自动配置的关键

        @Enable开头的注解,替代XML配置文件, @EnableWebMvc、@EnableScheduling // 注解之所以自动根据条件注册需要的Bean实例,主要是@Import注解导入此处@Import导入AutoConfigurationImportSelector的实现。

     1 @Target(ElementType.TYPE)
     2 @Retention(RetentionPolicy.RUNTIME)
     3 @Documented
     4 @Inherited
     5 @AutoConfigurationPackage
     6 @Import(AutoConfigurationImportSelector.class)
     7 public @interface EnableAutoConfiguration {
     8 
     9     String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
    10 
    11     Class<?>[] exclude() default {};
    12 
    13     String[] excludeName() default {};
    14 }

        AutoConfigurationImportSelector的selectImports -> getCandidateConfigurations -> SpringFactoriesLoader.loadFactoryNames

    List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
        Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
        return configurations;
    }

        类SpringFactoriesLoader定义常量 public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";

        而spring-boot-autoconfigure*.jar/META-INF/spring.factories部分配置

        

         spring-boot*jar\META-INF\spring.factories 部分

        

    2、SpringApplication.run

    内部实现流程

    1、如果使用run静态方法,那么该方法实例化一个SpringApplication对象,调用如下方法

      public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
        return new SpringApplication(primarySources).run(args);
      }

          初始化时,提前做几个事情(准备动作)

    • 根据classpath是否存在某特征类,决定是否创建供web应用使用的ApplicationContext类型
    • 使用SpringFactoriesLoader在应用classpath查找并加载所有可用的ApplicationContextInitializer
    • 使用SpringFactoriesLoader在应用classpatch查找并加载所有可用ApplicationListener

    2、SpingApplication实例初始化完成并完成设置后,开始执行run方法,首先遍历执行所有通过SpringFactoriesLoader查找到并加载的SpringApplicationRunListener,调用他们的Starting方法

    3、准备并配置当前spring boot应用要使用的Enviroment(含PropertySource和Profiles)

         protected void configureEnviroment(ConfirugurableEnviroment enviroment,String[] args){
              configurePropertySources(enviroment, args);

       configureProfiles(enviroment, args);

        }

    4、遍历执行所有SpringApplicationRunListener的enviromentPrepared() 方法,比如创建ApplicationContext

    5、判断SpringApplication的bannerMode,是CONSOLE则输出banner的System.out,是OFF则不打印,是LOG则打印到日志文件

    6、判断是否设置ApplicationContextClass属性,如果有,则实例化该class;如果没有则判断是否是web环境,如果是DEFAULT_WEB_CONTEXT_CLASS,则实例化该常量对应的AnnotationConfigEmbeddedWebApplicationContext类,否则实例化DEFAULT_CONTEXT_CLASS所对应的AnnotationConfigApplicationContext类,具体如下

      public static final String DEFAULT_CONTEXT_CLASS = "org.springframework.context.annotation.AnnotationConfigApplicationContext";

      public static final String DEFAULT_WEB_CONTEXT_CLASS = "org.springframework.context.embedded.AnnotationConfigEmbeddedWebApplicationContext";

    7、将之前准备好的enviroment配置给当前的ApplicationContext

    8、将beanNameGenerator、resourceLoader配置给当前的ApplicationContext

    9、SpringApplication通过SpringFactoriesLoader查找classpath中所有可用的AppliContextInitializer,遍历并加载ApplicationContextInitializer的initialize(context) 方法

    10、遍历执行所有SpringApplicationRunListener的contextPrepared() 方法

    11、为BeanDefinitionLoader配置beanNameGenerator、‘resourceLoader、enviroment,并加载之前通过@EnableAutoConfiguration获取的所有配置,及其余IOC容器配置到当前已准备完毕的ApplicationContext

    12、遍历执行所有SpringApplicationRunListener的contextLoader()方法

    13、调用ApplicationContext的refresh方法,完成IOC容器可用的最后工序,并为Runtime.getRuntime()添加ShutdownHook以遍JVM停止时优雅退出

    14、查找ApplicationContext是否注册ApplicationRunner或CommandLineRunner,并遍历执行

    15、遍历执行SpringApplicationRunListener的finished() 方法。

    -- 启动完成

  • 相关阅读:
    分支与循环(1)
    Python+selenium基本操作二
    python+selenium的八种定位方法
    变量与字符,数字连续
    Django虚拟环境拷贝到另一台电脑,不能直接使用的问题
    django部署到服务器使用manage.py runserver简单测试
    python中将main函数写成接口后main函数中的参数不能传递问题
    mac word2016尾部下划线不能显示
    简单的秒表实例
    Math.random理解练习
  • 原文地址:https://www.cnblogs.com/clarino/p/16344346.html
Copyright © 2020-2023  润新知