SpringBoot流程(上)

sin 2021-11-26 PM 709℃ 0条

SpringBoot启动流程

Spring启动流程,最重要的就是这个函数。我们也是从这里开始入手。

SpringApplication.run(DemoApplication.class, args);

在网上,我找到一个比较不错的分析图

png

启动代码主要分成2部分。

  • 构造SpringApplication
  • 执行run方法

构造SpringApplication

构造函数包括一系列重载函数,最后调用下面这个函数

@SuppressWarnings({ "unchecked", "rawtypes" })
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
    this.resourceLoader = resourceLoader;
    Assert.notNull(primarySources, "PrimarySources must not be null");
    this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
    // #1 侦测web application type
    this.webApplicationType = WebApplicationType.deduceFromClasspath();
    // #2 获取bootstrap registry initializers
    this.bootstrapRegistryInitializers = getBootstrapRegistryInitializersFromSpringFactories();
    // #3
    // 获取 ApplicationContextInitializer 设置initializers
    // 获取 ApplicationListener 设置listeners
    setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
    setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));

    // #4 获取main函数所在类
    this.mainApplicationClass = deduceMainApplicationClass();
}
1 侦测web application type

有三种类型的web application type

  • NONE
  • SERVLET
  • REACTIVE
2 获取bootstrap registry initializers

Bootstrapper 同时调用初始化

png

3 设置initializers和listener

修改一下代码,方便调试的时候可以直接查看变量

png

setInitializers只是简单的设置,不赘述

public void setInitializers(Collection<? extends ApplicationContextInitializer<?>> initializers) {
    this.initializers = new ArrayList<>(initializers);
}

listeners同理

png

获取实例的方法如下,我们跟进去看下代码易得

private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
    ClassLoader classLoader = getClassLoader();
    // Use names and ensure unique to protect against duplicates
    // 从每个包的META-INF/spring.factories处获取实现了对应接口的class
    Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));

    // 利用反射实例化!
    List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);

    // 根据order权重排序,初始化是有顺序的,数字越小越靠前
    AnnotationAwareOrderComparator.sort(instances);
    return instances;
}

png

png

4 获取main函数所在类
this.mainApplicationClass = deduceMainApplicationClass();

png

这一步,我们把定义的DemoApplication侦测到

参考

标签: none

非特殊说明,本博所有文章均为博主原创。

评论啦~