SpringApplication run方法 源码分析

java.awt.headless 参数说明

spring.beaninfo.ignore

“spring.beaninfo.ignore”,值为“true”表示跳过对BeanInfo类的搜索(通常用于首先没有为应用程序中的bean定义此类的情况)。

考虑到所有BeanInfo元数据类,默认值为“false”,例如标准的Introspector.getBeanInfo(Class)调用。

如果您遇到对不存在的BeanInfo类重复的ClassLoader访问,请考虑将此标志切换为“true”,以防此类访问在启动或延迟加载时很昂贵。

SpringApplication的run方法


public ConfigurableApplicationContext run(String... args) {
                 // 跑表,记录开始和结束时间
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();

                 // 一般是在程序开始激活headless模式,告诉程序,现在你要工作在Headless mode下,就不要指望硬件帮忙了,你得自力更生,依靠系统的计算能力模拟出这些特性来
        configureHeadlessProperty();

               //  META-INF/spring.factories文件中获取SpringApplicationRunListener接口的实现类。
        SpringApplicationRunListeners listeners = getRunListeners(args);
        listeners.starting(); // SpringApplicationRunListener监听器开启监听

        try {
                       // 保存args参数
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
                       // 准备环境变量, 读取application.properties文件中的环境变量
            ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);

                           // 跳过对不存在的BeanInfo类的搜索
            configureIgnoreBeanInfo(environment);


                         // 
            Banner printedBanner = printBanner(environment);

                         // 创建ApplicationContext, 即创建bean工厂
            context = createApplicationContext();
            exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
                    new Class[] { ConfigurableApplicationContext.class }, context);
                     //  将environment, listeners, applicationArguments, printedBanner等全部注册到bean工厂
            prepareContext(context, environment, listeners, applicationArguments, printedBanner);

                     // IoC容器开始创建bean实例
            refreshContext(context);

                  // IoC容器完成后
            afterRefresh(context, applicationArguments);
            stopWatch.stop();
            if (this.logStartupInfo) {
                new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
            }
            listeners.started(context);
                     // 回调 ApplicationRunner,CommandLineRunner
            callRunners(context, applicationArguments);
        }
        catch (Throwable ex) {
            handleRunFailure(context, ex, exceptionReporters, listeners);
            throw new IllegalStateException(ex);
        }

        try {
            listeners.running(context);
        }
        catch (Throwable ex) {
            handleRunFailure(context, ex, exceptionReporters, null);
            throw new IllegalStateException(ex);
        }
        return context;
    }


1、 SpringApplicationRunListener 监听器

Listener for the {@link SpringApplication} {@code run} method.

SpringApplicationRunListener用来监听SpringApplication的run方法;
用来回调CommandLineRunner,ApplicationRunner 对象实例的

2、根据key类型加载 META-INF/spring.factories 文件中的类。

org/springframework/boot/spring-boot/2.1.4.RELEASE/spring-boot-2.1.4.RELEASE.jar!/META-INF/spring.factories

SpringFactoriesLoader.loadFactoryNames(type, classLoader)
根据key类型加载 META-INF/spring.factories 文件中的类。


public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
        this.resourceLoader = resourceLoader; // null
        Assert.notNull(primarySources, "PrimarySources must not be null");
        this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
        this.webApplicationType = WebApplicationType.deduceFromClasspath();

  根据key类型加载 META-INF/spring.factories 文件中的ApplicationContextInitializer类。
        setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));

//根据key类型加载 META-INF/spring.factories 文件中的ApplicationListener类。
        setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
        this.mainApplicationClass = deduceMainApplicationClass();
    }
4165335-96cfecc40ed999d0.png
image.png

3、SpringApplication 加载META-INF/spring.factories文件中执行类型的key的过程

    private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
        ClassLoader classLoader = getClassLoader(); // 获取类加载器,默认当前线程的类加载器

        // Use names and ensure unique to protect against duplicates
// SpringFactoriesLoader根据type类型(key类型)加载加载spring.factories文件的类
        Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));

// 对获取到的类创建对象实例
        List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);

// 根据@Order或@Priority对对象实例排序
        AnnotationAwareOrderComparator.sort(instances);

        return instances;//返回对象实例
    }

自动配置启动流程

ConfigurationClassPostProcessor

ConfigurationClassParser

SpringApplication执行run方法

run方法执行 AbstractApplicationContext.refresh方法

在refresh方法中, 实现了对ConfigurationClassParser的调用。

AbstractApplicationContext.refresh方法

AbstractApplicationContext.refresh

// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

4165335-08e756708d174557.png
image.png
4165335-ad7a4d544a6b1879.png
image.png

ConfigurationClassPostProcessor

4165335-ba56a874fd30858d.png
image.png
4165335-cb27443238a3512f.png
image.png
4165335-61b02ad58c17c485.png
image.png
4165335-ba5a5767e23a2bf8.png
image.png

ConfigurationClassParser


4165335-96109c5a32813577.png
image.png

AnnotationConfigReactiveWebServerApplicationContext

创建是AnnotationConfigReactiveWebServerApplicationContext

4165335-f84d1d27b2f73673.png
image.png

BeanFactoryPostProcessor可以与bean定义交互并修改它们,但不能与bean实例交互。这样做可能会导致过早的bean实例化,违反容器并导致意外的副作用。如果需要bean实例交互,请考虑实现beanpstprocessor。

4165335-97e423a54afc601f.png
image.png
4165335-fb27c91808114dc5.png
image.png
4165335-faf2c294626ea664.png
image.png
4165335-1f12510b4f18591e.png
image.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值