SpringBoot run()方法解析

SpringBoot run()方法解析

SpringBoot在启动的时候,最终调用的是SpringApplication中的如下方法

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

new SpringApplication(primarySources)的源码如下:

创建SpringApplication对象

public SpringApplication(Class<?>... primarySources) {
        this(null, primarySources);
    }
    
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
        //获取资源加载器
        this.resourceLoader = resourceLoader;
        Assert.notNull(primarySources, "PrimarySources must not be null");
        this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
    //确定Web应用启动容器的类型,默认情况下为SERVLET
        this.webApplicationType = WebApplicationType.deduceFromClasspath();
    //实例化并加载所有可以加载的ApplicationContextInitializer
        setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
    //实例化并加载所有可以加载的ApplicationListener
        setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    //查找main方法的类对象
        this.mainApplicationClass = deduceMainApplicationClass();
    }

setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class))和setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));的调用实例如下

//根据给定的Class获取实例
    private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) {
        return getSpringFactoriesInstances(type, new Class<?>[] {});
    }

    private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
        ClassLoader classLoader = getClassLoader();
        // Use names and ensure unique to protect against duplicates
        Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
        //创建实例
        List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
        //对实例进行排序
        AnnotationAwareOrderComparator.sort(instances);
        return instances;
    }

下面就开始调用run方法

/**
     * 运行Spring Application,c创建并刷新ApplicationContext对象
     * {@link ApplicationContext}.
     * @param args the application arguments (usually passed from a Java main method)
     * @return a running {@link ApplicationContext}
     */
public ConfigurableApplicationContext run(String... args) {
    //用来统计总的线程的执行时间和当前线程的执行时间
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    //初始化应用上下文和异常报告集合
    ConfigurableApplicationContext context = null;
    Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
    //设置java.awt.headless的值,默认为true
    configureHeadlessProperty();
    //创建所有 Spring 运行监听器并发布应用启动事件
    SpringApplicationRunListeners listeners = getRunListeners(args);
    //启动各个SpringApplicationRunListener 监听器实例
    listeners.starting();
    try {
        //初始化默认参数
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        //根据运行监听器和应用参数来准备 Spring 环境
        ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
        configureIgnoreBeanInfo(environment);
        //创建Banner并打印banner的相关信息
        Banner printedBanner = printBanner(environment);
        //创建应用 上下文信息
        context = createApplicationContext();
        //异常报告
        exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
                new Class[] { ConfigurableApplicationContext.class }, context);
        //准备应用上下文信息
        prepareContext(context, environment, listeners, applicationArguments, printedBanner);
        //刷新应用下上文
        refreshContext(context);
        //应用上下文刷新后置处理
        afterRefresh(context, applicationArguments);
        stopWatch.stop();
        //输出日志记录执行的主类名等信息
        if (this.logStartupInfo) {
            new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
        }
        //发布应用上下文信息
        listeners.started(context);
        //执行所有 Runner 运行器
        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;
}

getRunListeners(args)获取监听器

private SpringApplicationRunListeners getRunListeners(String[] args) {
    Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
    return new SpringApplicationRunListeners(logger,
            getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));
}

猜你喜欢

转载自www.cnblogs.com/haizhilangzi/p/12443818.html
今日推荐