Spring Boot 启动时做了什么

注解

@SpringBootApplication注解 中包括三个注解:

  • @EnableAutoConfiguration:借助@Import的帮助,将所有符合自动配置条件的bean定义加载到IoC容器
  • @Configuration:Spring Ioc容器的配置类,
  • @ComponentScan:组件扫描,可自动发现和装配Bean,功能其实就是自动扫描并加载符合条件的组件或者bean定义,最终将这些bean定义加载到IoC容器中.默认扫描SpringApplication的run方法里的class所在的包路径下文件,所以最好将该启动类放到根包路径下

启动方法

创建SpringApplication实例

    public SpringApplication(Class... primarySources) {
        this((ResourceLoader)null, primarySources);
    }

    public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) {
        this.sources = new LinkedHashSet();
        this.bannerMode = Mode.CONSOLE;
        this.logStartupInfo = true;
        this.addCommandLineProperties = true;
        this.addConversionService = true;
        this.headless = true;
        this.registerShutdownHook = true;
        this.additionalProfiles = new HashSet();
        this.isCustomEnvironment = false;
        this.lazyInitialization = false;
        // 初始化资源加载器
        this.resourceLoader = resourceLoader;
        // 断言主要资源类不为空
        Assert.notNull(primarySources, "PrimarySources must not be null");
        // 初始化主要加载资源类集合
        this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
        // 判断项目类型
        this.webApplicationType = WebApplicationType.deduceFromClasspath();
        // 设置初始化器
        this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
        //设置监听器
        this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
        //推断程序主类
        this.mainApplicationClass = this.deduceMainApplicationClass();
    }

初始化主要加载资源类集合

判断项目类型

	public enum WebApplicationType {
		NONE,
	    SERVLET,
	    REACTIVE;
	
	    private static final String[] SERVLET_INDICATOR_CLASSES = new String[]{"javax.servlet.Servlet", "org.springframework.web.context.ConfigurableWebApplicationContext"};
	    private static final String WEBMVC_INDICATOR_CLASS = "org.springframework.web.servlet.DispatcherServlet";
	    private static final String WEBFLUX_INDICATOR_CLASS = "org.springframework.web.reactive.DispatcherHandler";
	    private static final String JERSEY_INDICATOR_CLASS = "org.glassfish.jersey.servlet.ServletContainer";
	    private static final String SERVLET_APPLICATION_CONTEXT_CLASS = "org.springframework.web.context.WebApplicationContext";
	    private static final String REACTIVE_APPLICATION_CONTEXT_CLASS = "org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext";
	
	    private WebApplicationType() {
	    }
	
	    static WebApplicationType deduceFromClasspath() {
	        if (ClassUtils.isPresent("org.springframework.web.reactive.DispatcherHandler", (ClassLoader)null) && !ClassUtils.isPresent("org.springframework.web.servlet.DispatcherServlet", (ClassLoader)null) && !ClassUtils.isPresent("org.glassfish.jersey.servlet.ServletContainer", (ClassLoader)null)) {
	            return REACTIVE;
	        } else {
	            String[] var0 = SERVLET_INDICATOR_CLASSES;
	            int var1 = var0.length;
	
	            for(int var2 = 0; var2 < var1; ++var2) {
	                String className = var0[var2];
	                if (!ClassUtils.isPresent(className, (ClassLoader)null)) {
	                    return NONE;
	                }
	            }
	
	            return SERVLET;
	        }
	    }
	}

根据classpath中是否包含指定类
1.REACTIVE:ClassUtils.isPresent("org.springframework.web.reactive.DispatcherHandler", (ClassLoader)null) && !ClassUtils.isPresent("org.springframework.web.servlet.DispatcherServlet", (ClassLoader)null) && !ClassUtils.isPresent("org.glassfish.jersey.servlet.ServletContainer", (ClassLoader)null)
2.SERVLET:(!ClassUtils.isPresent("javax.servlet.Servlet", (ClassLoader)null)) && (!ClassUtils.isPresent("org.springframework.web.context.ConfigurableWebApplicationContext", (ClassLoader)null))
3.NONE

设置应用上线文初始化器 ApplicationContextInitializer

路径下META-INF/spring.factories文件ApplicationContextInitializer 接口的所有配置的类路径名称,用来初始化指定的 Spring 应用上下文,如注册属性资源、激活 Profiles 等。

  1. 获取类加载器
  2. 获取ApplicationContextInitializer实例名称
  3. 创建初始化器实例
  4. 给初始化器实例排序

设置监听器 ApplicationListener

路径下META-INF/spring.factories文件,使用初始化器相同的方法设置

设置程序的主类

执行run方法

猜你喜欢

转载自www.cnblogs.com/herberts/p/13178161.html