• SpringApplication执行流程


    SpringApplication类的直接作用是在main方法中通过自有的run方法启动spring应用。

    具体的run方法为:

    public static ConfigurableApplicationContext run(Object source, String... args)

    该方法最终会把source传给SpringApplication的构造方法中的初始化方法:

    private void initialize(Object[] sources) {
    
       if (sources != null && sources.length > 0) {
    
          this.sources.addAll(Arrays.asList(sources));
    
       }
    
       this.webEnvironment = deduceWebEnvironment();
    
       setInitializers((Collection) getSpringFactoriesInstances(
    
             ApplicationContextInitializer.class));
    
       setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    
       this.mainApplicationClass = deduceMainApplicationClass();
    
    }

    该初始化方法一共做了以下几件事:

    一、判断sourse长度

    首先,如果sources长度大于0(即是数组或容器),则把这些sources全部传到内置的hashset中。由此可见,run方法的第一个参数中是可以传入多个source的。

    二、判断web环境是否正确

    this.webEnvironment = deduceWebEnvironment();

    判断整个环境中是否存在javax.servlet.Servlet类和

    org.springframework.web.context.ConfigurableWebApplicationContext类这两个类,如果存在话,则表示web环境正常,返回true,否则返回false。

    三、设置Initializers

    首先会调getSpringFactoriesInstances方法加载ApplicationContextInitializer类,这个方法最终会运行SpringFactoriesLoader.loadFactoryNames方法,这个方法的目的是从“META-INF/spring.factories文件”中加载配置。

    可实际上我们一般在开发springboot项目时并没有创建过spring.factories文件,可还是自动加载了各种配置,原因如下:

    在项目的main方法上一般都会设置@SpringBootApplication注解,@SpringBootApplication注解中包含了多个注解,其中有一个@EnableAutoConfiguration注解尤为重要。

    通过@EnableAutoConfiguration注解会将org.springframework.boot.autoconfigure.EnableAutoConfiguration这个包作为查找META-INF/spring.factories文件的根目录,即spring.factories文件会从org.springframework.boot.autoconfigure.EnableAutoConfiguration包中查找。而这个包里面自然有已经写好的spring.factories文件了。

    整个springboot中会看到很多@Enable开头的注解,所有的@Enable开头的注解的作用都是通过@Import将“特定的bean”加载到Ioc容器中。@EnableAutoConfiguration的作用就是通过SpringFactoriesLoader将所有的标注了@Configuration注解的类加载(既有boot.autoconfigure包自带的标注了@Configuration的类,也可以是自己创建的标注了@Configration的类,都会被作为配置加载)

    四、设置Listeners

    listener的加载与之前的Initializers加载同理,都是寻找META-INF/spring.factories文件,然后被@EnableAutoConfiguration注解把路径转移到了org.springframework.boot.autoconfigure.EnableAutoConfiguration/META-INF/spring.factories中,之后就能找到已经提前写好的相关监听配置了。

    五、设置mainApplicationClass

    private Class<?> deduceMainApplicationClass() {
    
       try {
    
          StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
    
          for (StackTraceElement stackTraceElement : stackTrace) {
    
             if ("main".equals(stackTraceElement.getMethodName())) {
    
                return Class.forName(stackTraceElement.getClassName());
    
             }
    
          }
    
       }
    
       catch (ClassNotFoundException ex) {
    
          // Swallow and continue
    
       }
    
       return null;
    
    }

    该方法是通过遍历栈,找到main方法,从而找到启动类,并将其赋值给mainApplicationClass属性。

  • 相关阅读:
    后端开发应该掌握的 Redis 基础
    Code Review有什么好处?
    对不起,你那不叫努力,叫重复劳动
    老鸟程序员才知道的40个小技巧
    单例模式基础笔记
    最受IT公司欢迎的50款开源软件
    硬件:关于路由器、交换机、宽带猫的几个问题
    硬件:宽带猫(光猫)的基础知识
    python selenium模块使用出错解决,Message: ‘geckodriver’ executable needs to be in PATH
    python+selenium如何定位页面的元素,的几种定位元素的方法。
  • 原文地址:https://www.cnblogs.com/red-code/p/9267106.html
Copyright © 2020-2023  润新知