springboot源码分析01

springboot启动流程源码分析

SpringApplication.run(MessageApplication.class, args);
springboot项目启动主入口如上所示。
/**
     * Static helper that can be used to run a {@link SpringApplication} from the
     * specified source using default settings.
     * @param primarySource the primary source to load
     * @param args the application arguments (usually passed from a Java main method)
     * @return the running {@link ApplicationContext}
     */
    public static ConfigurableApplicationContext run(Class primarySource,
            String... args) {
        return run(new Class[] { primarySource }, args);
    }

一般来说这里是调用传入反射类实例构造方法,当着这里的反射的类实例也可以是数组形式,同时启动多个入口,启动顺序根据反射类数组的顺序决定。

首先来粗略的说是springboot的构造部分:
主要springboot启动的初始化方法
/**
     * Create a new {@link SpringApplication} instance. The application context will load
     * beans from the specified primary sources (see {@link SpringApplication class-level}
     * documentation for details. The instance can be customized before calling
     * {@link #run(String...)}.
     * @param resourceLoader the resource loader to use
     * @param primarySources the primary bean sources
     * @see #run(Class, String[])
     * @see #setSources(Set)
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) {
  //  这里是引入了资源加载器,
        this.resourceLoader = resourceLoader;
        Assert.notNull(primarySources, "PrimarySources must not be null");
//如果有多个主加载入口的话,会把它们转为一个linkedHashSet
        this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
//设置应用的类型是servlet还是其他别的
        this.webApplicationType = deduceWebApplicationType();
//从spring.factories中获取初始化应用需要的容器
        setInitializers((Collection) getSpringFactoriesInstances(
                ApplicationContextInitializer.class));
//从spring.factories中获取初始化应用需要的监听器
        setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
//已main方法作为程序的主入口
        this.mainApplicationClass = deduceMainApplicationClass();
    }
接下来我们实际上可以看到,构造完了之后执行了一个run方法
    /**
     * Static helper that can be used to run a {@link SpringApplication} from the
     * specified sources using default settings and user supplied arguments.
     * @param primarySources the primary sources to load
     * @param args the application arguments (usually passed from a Java main method)
     * @return the running {@link ApplicationContext}
     */
    public static ConfigurableApplicationContext run(Class[] primarySources,
            String[] args) {
        return new SpringApplication(primarySources).run(args);
    }
接下来才是重头戏,spring开始创建和刷新应用上下文了。
/**
     * Run the Spring application, creating and refreshing a new
     * {@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声明,主要是提供一个需要上下的实现
        ConfigurableApplicationContext context = null;
//这里是异常处理器
        Collection exceptionReporters = new ArrayList<>();
        configureHeadlessProperty();
//// 获取SpringApplicationRunListeners,内部只有一个EventPublishingRunListener
        SpringApplicationRunListeners listeners = getRunListeners(args);
        listeners.starting();
        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(
                    args);
            ConfigurableEnvironment environment = prepareEnvironment(listeners,
                    applicationArguments);
//加载环境配置文件例如 bootstrap.yml
            configureIgnoreBeanInfo(environment);
            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);
            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;
    }

未完待续>>>

你可能感兴趣的:(springboot源码分析01)