zoukankan      html  css  js  c++  java
  • spring boot 源码之SpringApplication

    run方法

      run方法主要创建和初始化ConfigurableApplicationContext,在各个节点调用SpringApplicationRunListener的回调函数,在发送异常时调用用户自定义SpringBootExceptionReporter。调用ApplicationRunner和CommandLineRunner的run方法。

    public static ConfigurableApplicationContext run(Class<?>[] primarySources,
                String[] args) {
            return new SpringApplication(primarySources).run(args);
        }
    public ConfigurableApplicationContext run(String... args) {
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            ConfigurableApplicationContext context = null;
            Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
            configureHeadlessProperty();
        //获取SpringApplicationRunListeners并调用starting方法 SpringApplicationRunListeners listeners
    = getRunListeners(args); listeners.starting(); try { ApplicationArguments applicationArguments = new DefaultApplicationArguments( args); ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments); configureIgnoreBeanInfo(environment); Banner printedBanner = printBanner(environment); context = createApplicationContext(); //创建springApplicationContext exceptionReporters = getSpringFactoriesInstances( SpringBootExceptionReporter.class, new Class[] { ConfigurableApplicationContext.class }, context);//获取SpringBootExceptionReporter prepareContext(context, environment, listeners, applicationArguments, printedBanner);//使用springApplicationContext准备 refreshContext(context);//使用springApplicationContext的refresh方法 afterRefresh(context, applicationArguments);//refresh后的回调函数 listeners.finished(context, null);//调用SpringApplicationRunListener的finished方法 stopWatch.stop(); if (this.logStartupInfo) { new StartupInfoLogger(this.mainApplicationClass) .logStarted(getApplicationLog(), stopWatch); } callRunners(context, applicationArguments); return context; } catch (Throwable ex) { handleRunFailure(context, listeners, exceptionReporters, ex);//处理异常 throw new IllegalStateException(ex); } }

     getRunListeners

      通过SpringFactoriesLoader从META-INF/spring.factories获取配置的SpringApplicationRunListener并初始化这些类。

    private SpringApplicationRunListeners getRunListeners(String[] args) {
            Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
            return new SpringApplicationRunListeners(logger, getSpringFactoriesInstances(
                    SpringApplicationRunListener.class, types, this, args));
        }
        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 = Thread.currentThread().getContextClassLoader();
            // 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;
        }
        @SuppressWarnings("unchecked")
        private <T> List<T> createSpringFactoriesInstances(Class<T> type,
                Class<?>[] parameterTypes, ClassLoader classLoader, Object[] args,
                Set<String> names) {
            List<T> instances = new ArrayList<>(names.size());
            for (String name : names) {
                try {
                    Class<?> instanceClass = ClassUtils.forName(name, classLoader);
                    Assert.isAssignable(type, instanceClass);
                    Constructor<?> constructor = instanceClass
                            .getDeclaredConstructor(parameterTypes);
                    T instance = (T) BeanUtils.instantiateClass(constructor, args);
                    instances.add(instance);
                }
                catch (Throwable ex) {
                    throw new IllegalArgumentException(
                            "Cannot instantiate " + type + " : " + name, ex);
                }
            }
            return instances;
        }

     createApplicationContext

      根据不同的应用类型,初始化不同的ApplicationContext。

    
    
    public static final String DEFAULT_CONTEXT_CLASS = "org.springframework.context."
    + "annotation.AnnotationConfigApplicationContext";
    
    
    public static final String DEFAULT_WEB_CONTEXT_CLASS = "org.springframework.boot."
    + "web.servlet.context.AnnotationConfigServletWebServerApplicationContext";
    
    
    public static final String DEFAULT_REACTIVE_WEB_CONTEXT_CLASS = "org.springframework."
    + "boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext";

    protected
    ConfigurableApplicationContext createApplicationContext() { Class<?> contextClass = this.applicationContextClass; if (contextClass == null) { try { switch (this.webApplicationType) { case SERVLET: contextClass = Class.forName(DEFAULT_WEB_CONTEXT_CLASS); break; case REACTIVE: contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS); break; default: contextClass = Class.forName(DEFAULT_CONTEXT_CLASS); } } catch (ClassNotFoundException ex) { throw new IllegalStateException( "Unable create a default ApplicationContext, " + "please specify an ApplicationContextClass", ex); } } return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass); }

     callRunners方法

      从spring容器中获取所有的ApplicationRunner和CommandLineRunner然后调用他们的run方法。

    private void callRunners(ApplicationContext context, ApplicationArguments args) {
            List<Object> runners = new ArrayList<>();
            runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
            runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
            AnnotationAwareOrderComparator.sort(runners);
            for (Object runner : new LinkedHashSet<>(runners)) {
                if (runner instanceof ApplicationRunner) {
                    callRunner((ApplicationRunner) runner, args);
                }
                if (runner instanceof CommandLineRunner) {
                    callRunner((CommandLineRunner) runner, args);
                }
            }
        }
  • 相关阅读:
    【bzoj4152】[AMPPZ2014]The Captain 堆优化Dijkstra
    【bzoj4547】Hdu5171 小奇的集合 矩阵乘法
    【bzoj1264】[AHOI2006]基因匹配Match 树状数组
    【bzoj3856】Monster 乱搞
    【bzoj4724】[POI2017]Podzielno 二分
    【bzoj4976】宝石镶嵌 乱搞+dp
    【bzoj4070】[Apio2015]雅加达的摩天楼 set+堆优化Dijkstra
    【bzoj4627】[BeiJing2016]回转寿司 离散化+树状数组
    【bzoj2124】等差子序列 STL-bitset
    【bzoj1996】[Hnoi2010]chorus 合唱队 区间dp
  • 原文地址:https://www.cnblogs.com/zhangwanhua/p/7930546.html
Copyright © 2011-2022 走看看