第七章:(1)Spring Boot启动原理

一、SpringBoot 启动原理

  运行一个主程序类的 main 方法:

---主程序运行---
@SpringBootApplication
public class SpringBoot07RunApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBoot07RunApplication.class, args);
    }

}

---SpringApplication---
public static ConfigurableApplicationContext run(Object source, String... args) {
    return run(new Object[] { source }, args);
}

public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
    return new SpringApplication(sources).run(args);
}

  启动流程:

  1、创建 SpringApplication 对象

  2、运行 run 方法 

二、创建 SpringApplication 对象

  创建 SpringApplication 应用:

public SpringApplication(Object... sources) {
    initialize(sources);
}

private void initialize(Object[] sources) {
    //1、保存主配置类
    if (sources != null && sources.length > 0) {
        this.sources.addAll(Arrays.asList(sources));
    }
    
    //2、判断当前是否一个web应用
    this.webEnvironment = deduceWebEnvironment();
    
    //3、从类路径下找到META‐INF/spring.factories配置的所有ApplicationContextInitializer;然后保存起来
    setInitializers((Collection) getSpringFactoriesInstances(
            ApplicationContextInitializer.class));
            
    //4、从类路径下找到ETA‐INF/spring.factories配置的所有ApplicationListener        
    setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    
    //5、决定主配置类:从多个配置类中找到有main方法的主配置类
    this.mainApplicationClass = deduceMainApplicationClass();
}

  (1)保存主配置类

if (sources != null && sources.length > 0) {
    this.sources.addAll(Arrays.asList(sources));
}

  (2)判断当前是否一个 web 应用

private boolean deduceWebEnvironment() {
    for (String className : WEB_ENVIRONMENT_CLASSES) {
        if (!ClassUtils.isPresent(className, null)) {
            return false;
        }
    }
    return true;
}

  (3)加载类路径下找到META‐INF/spring.factories配置的所有ApplicationContextInitializer 组件

//设置初始化器
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
                
public void setInitializers(
        Collection<? extends ApplicationContextInitializer<?>> initializers) {
    this.initializers = new ArrayList<ApplicationContextInitializer<?>>();
    this.initializers.addAll(initializers);
}

private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type) {
    return getSpringFactoriesInstances(type, new Class<?>[] {});
}

private <T> Collection<? extends 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<String>(
            SpringFactoriesLoader.loadFactoryNames(type, classLoader));
    List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
            classLoader, args, names);
    AnnotationAwareOrderComparator.sort(instances);
    return instances;
}

public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
    String factoryClassName = factoryClass.getName();
    try {
        Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
                ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
        List<String> result = new ArrayList<String>();
        while (urls.hasMoreElements()) {
            URL url = urls.nextElement();
            Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
            String factoryClassNames = properties.getProperty(factoryClassName);
            result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
        }
        return result;
    }
    catch (IOException ex) {
        throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() +
                "] factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex);
    }
}

    

  (4)从类路径下找到ETA‐INF/spring.factories配置的所有ApplicationListener 组件

setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));

public void setListeners(Collection<? extends ApplicationListener<?>> listeners) {
    this.listeners = new ArrayList<ApplicationListener<?>>();
    this.listeners.addAll(listeners);
}

private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type) {
    return getSpringFactoriesInstances(type, new Class<?>[] {});
}

private <T> Collection<? extends 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<String>(
            SpringFactoriesLoader.loadFactoryNames(type, classLoader));
    List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
            classLoader, args, names);
    AnnotationAwareOrderComparator.sort(instances);
    return instances;
}

    

  (5)决定主配置类

private Class<?> deduceMainApplicationClass() {
    try {
        StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
        for (StackTraceElement stackTraceElement : stackTrace) {
            if ("main".equals(stackTraceElement.getMethodName())) {
                return Class.forName(stackTraceElement.getClassName());
            }
        }
    }
    catch (ClassNotFoundException ex) {
        // Swallow and continue
    }
    return null;
}

三、运行 run 方法

  来到 SpringBootApplication 的 run 方法

public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
    return new SpringApplication(sources).run(args);
}

public ConfigurableApplicationContext run(String... args) {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    ConfigurableApplicationContext context = null;
    FailureAnalyzers analyzers = null;
    //AWT 相关
    configureHeadlessProperty();
    
    //1、获取SpringApplicationRunListeners;从类路径下META‐INF/spring.factories
    SpringApplicationRunListeners listeners = getRunListeners(args);
    //回调所有的获取SpringApplicationRunListener.starting()方法
    listeners.starting();
    
    try {
        //封装命令行参数
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        
        
        //2、准备环境
        ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
        //创建环境完成后回调SpringApplicationRunListener.environmentPrepared();表示环境准备完成        

                
        //打印 Banner 图        
        Banner printedBanner = printBanner(environment);
        
        
        //3、创建ApplicationContext;决定创建web的ioc还是普通的ioc
        context = createApplicationContext();
        
        
        //异常分析报告
        analyzers = new FailureAnalyzers(context);
        
        
        //4、准备上下文环境;将environment保存到ioc中;而且applyInitializers();
        // applyInitializers():回调之前保存的所有的ApplicationContextInitializer的initialize方法
        // 回调所有的SpringApplicationRunListener的contextPrepared();
        prepareContext(context, environment, listeners, applicationArguments, printedBanner);
        //prepareContext运行完成以后回调所有的SpringApplicationRunListener的contextLoaded();
        
        
        //5、刷新容器;ioc容器初始化(如果是web应用还会创建嵌入式的Tomcat)
        //扫描,创建,加载所有组件的地方;(配置类,组件,自动配置)
        refreshContext(context);
        
        
        //6、从ioc容器中获取所有的ApplicationRunner和CommandLineRunner进行回调
        //   ApplicationRunner先回调,CommandLineRunner再回调
        afterRefresh(context, applicationArguments);
        
        
        //7、所有的SpringApplicationRunListener回调finished方法
        listeners.finished(context, null);
        
        stopWatch.stop();
        if (this.logStartupInfo) {
            new StartupInfoLogger(this.mainApplicationClass)
                    .logStarted(getApplicationLog(), stopWatch);
        }
        
        //8、整个SpringBoot应用启动完成以后返回启动的ioc容器;
        return context;
    }
    catch (Throwable ex) {
        handleRunFailure(context, listeners, analyzers, ex);
        throw new IllegalStateException(ex);
    }
}

  核心步骤:

  (1)获取所有的 SpringApplicationRunListener 组件,并回调 starting 方法

//从类路径下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));
}

//回调SpringApplicationRunListener的 starting 方法
public void starting() {
    for (SpringApplicationRunListener listener : this.listeners) {
        listener.starting();
    }
}

  (2)准备环境

//准备环境
private ConfigurableEnvironment prepareEnvironment(
        SpringApplicationRunListeners listeners,
        ApplicationArguments applicationArguments) {
    // Create and configure the environment
    //得到或者创建一个环境
    ConfigurableEnvironment environment = getOrCreateEnvironment();
    //配置环境
    configureEnvironment(environment, applicationArguments.getSourceArgs());
    
    //创建环境完成后回调SpringApplicationRunListener.environmentPrepared();表示环境准备完成
    listeners.environmentPrepared(environment);
    
    //是否为 web 环境
    if (!this.webEnvironment) {
        environment = new EnvironmentConverter(getClassLoader())
                .convertToStandardEnvironmentIfNecessary(environment);
    }
    return environment;
}
public void environmentPrepared(ConfigurableEnvironment environment) {
    for (SpringApplicationRunListener listener : this.listeners) {
        listener.environmentPrepared(environment);
    }
}

  (3)创建 ApplicationContext

protected ConfigurableApplicationContext createApplicationContext() {
    Class<?> contextClass = this.applicationContextClass;
    if (contextClass == null) {
        try {
            contextClass = Class.forName(this.webEnvironment
                    ? DEFAULT_WEB_CONTEXT_CLASS : DEFAULT_CONTEXT_CLASS);
        }
        catch (ClassNotFoundException ex) {
            throw new IllegalStateException(
                    "Unable create a default ApplicationContext, "
                            + "please specify an ApplicationContextClass",
                    ex);
        }
    }
    //创建ApplicationContext;决定创建web的ioc还是普通的ioc
    return (ConfigurableApplicationContext) BeanUtils.instantiate(contextClass);
}

  (4)准备上下文环境

//准备上下文环境
private void prepareContext(ConfigurableApplicationContext context,
        ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
        ApplicationArguments applicationArguments, Banner printedBanner) {
    //设置上下文环境    
    context.setEnvironment(environment);
    //通过后置处理器添加组件
    postProcessApplicationContext(context);
    
    //回调之前保存的所有的ApplicationContextInitializer的initialize方法
    applyInitializers(context);
    
    //回调所有的SpringApplicationRunListener的contextPrepared();
    listeners.contextPrepared(context);
if (this.logStartupInfo) { logStartupInfo(context.getParent() == null); logStartupProfileInfo(context); } // Add boot specific singleton beans context.getBeanFactory().registerSingleton("springApplicationArguments", applicationArguments); if (printedBanner != null) { context.getBeanFactory().registerSingleton("springBootBanner", printedBanner); } // Load the sources Set<Object> sources = getSources(); Assert.notEmpty(sources, "Sources must not be empty"); load(context, sources.toArray(new Object[sources.size()])); //context 设置完毕后,回调所有的SpringApplicationRunListener的contextLoaded() listeners.contextLoaded(context); } protected void applyInitializers(ConfigurableApplicationContext context) { for (ApplicationContextInitializer initializer : getInitializers()) { Class<?> requiredType = GenericTypeResolver.resolveTypeArgument( initializer.getClass(), ApplicationContextInitializer.class); Assert.isInstanceOf(requiredType, context, "Unable to call initializer."); initializer.initialize(context); } } public void contextPrepared(ConfigurableApplicationContext context) { for (SpringApplicationRunListener listener : this.listeners) { listener.contextPrepared(context); } } public void contextLoaded(ConfigurableApplicationContext context) { for (SpringApplicationRunListener listener : this.listeners) { listener.contextLoaded(context); } }

  (5)刷新容器,IOC 容器初始化

private void refreshContext(ConfigurableApplicationContext context) {
    refresh(context);
    if (this.registerShutdownHook) {
        try {
            context.registerShutdownHook();
        }
        catch (AccessControlException ex) {
            // Not allowed in some environments.
        }
    }
}

  (6)从 IOC 容器中获取所有的ApplicationRunner和CommandLineRunner进行回调

protected void afterRefresh(ConfigurableApplicationContext context,
        ApplicationArguments args) {
    callRunners(context, args);
}

private void callRunners(ApplicationContext context, ApplicationArguments args) {
    List<Object> runners = new ArrayList<Object>();
    runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
    runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
    AnnotationAwareOrderComparator.sort(runners);
    for (Object runner : new LinkedHashSet<Object>(runners)) {
        if (runner instanceof ApplicationRunner) {
            callRunner((ApplicationRunner) runner, args);
        }
        if (runner instanceof CommandLineRunner) {
            callRunner((CommandLineRunner) runner, args);
        }
    }
}

private void callRunner(ApplicationRunner runner, ApplicationArguments args) {
    try {
        (runner).run(args);
    }
    catch (Exception ex) {
        throw new IllegalStateException("Failed to execute ApplicationRunner", ex);
    }
}

private void callRunner(CommandLineRunner runner, ApplicationArguments args) {
    try {
        (runner).run(args.getSourceArgs());
    }
    catch (Exception ex) {
        throw new IllegalStateException("Failed to execute CommandLineRunner", ex);
    }
}

  (7)所有的SpringApplicationRunListener回调finished方法

public void finished(ConfigurableApplicationContext context, Throwable exception) {
    for (SpringApplicationRunListener listener : this.listeners) {
        callFinishedListener(listener, context, exception);
    }
}

  (8)整个SpringBoot应用启动完成以后返回启动的ioc容器

四、启动原理总结

   SpringApplication.run(主程序类)

  1、new SpringApplication(主程序类)

    (1)判断是否 web 应用;

    (2)加载并保存所有ApplicationContextInitializer( META-INF/spring.factories

    (3)加载并保存所有ApplicationListener

    (4)获取到主程序类

  2、run()

    (1)回调所有的SpringApplicationRunListener( META-INF/spring.factories)的starting
    (2)获取ApplicationArguments
    (3)准备环境&回调所有监听器( SpringApplicationRunListener )的environmentPrepared
    (4)打印banner信息
    (5)创建ioc容器对象

AnnotationConfigEmbeddedWebApplicationContext( web环境容器)
AnnotationConfigApplicationContext(普通环境容器)

  3、run()

    (1)准备环境
      ① 执行ApplicationContextInitializer. initialize()
      ② 监听器SpringApplicationRunListener回调contextPrepared
      ③ 加载主配置类定义信息
      ④ 监听器SpringApplicationRunListener回调contextLoaded
    (2)刷新启动IOC容器;
      ① 扫描加载所有容器中的组件
      ② 包括从META-INF/spring.factories中获取的所有EnableAutoConfiguration组件
    (3)回调容器中所有的ApplicationRunnerCommandLineRunner的run方法
    (4)监听器SpringApplicationRunListener回调finished;

  4、几个重要的事件回调机制

    配置在 META-INF/spring.factories

ApplicationContextInitializer
SpringApplicationRunListener

    只需要放在 IOC 容器中

ApplicationRunner
CommandLineRunner

  

五、SpringBoot 事件监听机制

  根据上面的流程,可以实现自己的组件:

  (1)HelloApplicationContextInitializer

//IOC容器的初始化
public class HelloApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        System.out.println("IOC容器初始化~~");
        System.out.println("ApplicationContextInitializer...initialize..."+applicationContext);
    }
}

  (2)HelloSpringApplicationRunListener

public class HelloSpringApplicationRunListener implements SpringApplicationRunListener {

    //必须有的构造器
    public HelloSpringApplicationRunListener(SpringApplication application, String[] args){
    }

    //创建IOC容器之前
    @Override
    public void starting() {
        System.out.println("准备开始创建IOC容器~~~");
        System.out.println("SpringApplicationRunListener...starting...");
    }

    //环境准备完毕
    @Override
    public void environmentPrepared(ConfigurableEnvironment environment) {
        System.out.println("环境准备完毕");
        Object os = environment.getSystemProperties().get("os.name");
        System.out.println("SpringApplicationRunListener...environmentPrepared.."+ os);
    }

    //准备上下文context
    @Override
    public void contextPrepared(ConfigurableApplicationContext context) {
        System.out.println("准备上下文 context");
        System.out.println("SpringApplicationRunListener...contextPrepared...");
    }

    //context 准备完毕
    @Override
    public void contextLoaded(ConfigurableApplicationContext context) {
        System.out.println("context 准备完毕");
        System.out.println("SpringApplicationRunListener...contextLoaded...");
    }

    //IOC容器创建完毕
    @Override
    public void finished(ConfigurableApplicationContext context, Throwable exception) {
        System.out.println("IOC容器创建完毕");
        System.out.println("SpringApplicationRunListener...finished...");
    }
}

  (3)HelloApplicationRunner

@Component
public class HelloApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("ApplicationRunner...run....");
    }
}

  (4)HelloCommandLineRunner

@Component
public class HelloCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("CommandLineRunner...run..."+ Arrays.asList(args));
    }
}

  进行配置:

  ApplicationContextInitializer 与 SpringApplicationRunListener 需要配置在 META-INF/spring.factories

org.springframework.context.ApplicationContextInitializer=\
  com.njf.springboot.listener.HelloApplicationContextInitializer

org.springframework.boot.SpringApplicationRunListener=\
  com.njf.springboot.listener.HelloSpringApplicationRunListener

     

   ApplicationRunner 和 CommandLineRunner 加在 IOC 容器中

  测试:

D:\Java\JDK8\jdk1.8.0_231\bin\java.exe -XX:TieredStopAtLevel=1 -noverify -Dspring.output.ansi.enabled=always "-javaagent:D:\Java-IDE\JetBrains\IntelliJ IDEA 2021.1\lib\idea_rt.jar=7735:D:\Java-IDE\JetBrains\IntelliJ IDEA 2021.1\bin" -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true -Dfile.encoding=UTF-8 -classpath D:\Java\JDK8\jdk1.8.0_231\jre\lib\charsets.jar;D:\Java\JDK8\jdk1.8.0_231\jre\lib\deploy.jar;D:\Java\JDK8\jdk1.8.0_231\jre\lib\ext\access-bridge-64.jar;D:\Java\JDK8\jdk1.8.0_231\jre\lib\ext\cldrdata.jar;D:\Java\JDK8\jdk1.8.0_231\jre\lib\ext\dnsns.jar;D:\Java\JDK8\jdk1.8.0_231\jre\lib\ext\jaccess.jar;D:\Java\JDK8\jdk1.8.0_231\jre\lib\ext\jfxrt.jar;D:\Java\JDK8\jdk1.8.0_231\jre\lib\ext\localedata.jar;D:\Java\JDK8\jdk1.8.0_231\jre\lib\ext\nashorn.jar;D:\Java\JDK8\jdk1.8.0_231\jre\lib\ext\sunec.jar;D:\Java\JDK8\jdk1.8.0_231\jre\lib\ext\sunjce_provider.jar;D:\Java\JDK8\jdk1.8.0_231\jre\lib\ext\sunmscapi.jar;D:\Java\JDK8\jdk1.8.0_231\jre\lib\ext\sunpkcs11.jar;D:\Java\JDK8\jdk1.8.0_231\jre\lib\ext\zipfs.jar;D:\Java\JDK8\jdk1.8.0_231\jre\lib\javaws.jar;D:\Java\JDK8\jdk1.8.0_231\jre\lib\jce.jar;D:\Java\JDK8\jdk1.8.0_231\jre\lib\jfr.jar;D:\Java\JDK8\jdk1.8.0_231\jre\lib\jfxswt.jar;D:\Java\JDK8\jdk1.8.0_231\jre\lib\jsse.jar;D:\Java\JDK8\jdk1.8.0_231\jre\lib\management-agent.jar;D:\Java\JDK8\jdk1.8.0_231\jre\lib\plugin.jar;D:\Java\JDK8\jdk1.8.0_231\jre\lib\resources.jar;D:\Java\JDK8\jdk1.8.0_231\jre\lib\rt.jar;F:\My_Workspaceing\project\SpringBoot\spring-boot-07-run\target\classes;D:\RepMaven\repos\org\springframework\boot\spring-boot-starter-web\1.5.9.RELEASE\spring-boot-starter-web-1.5.9.RELEASE.jar;D:\RepMaven\repos\org\springframework\boot\spring-boot-starter\1.5.9.RELEASE\spring-boot-starter-1.5.9.RELEASE.jar;D:\RepMaven\repos\org\springframework\boot\spring-boot\1.5.9.RELEASE\spring-boot-1.5.9.RELEASE.jar;D:\RepMaven\repos\org\springframework\boot\spring-boot-autoconfigure\1.5.9.RELEASE\spring-boot-autoconfigure-1.5.9.RELEASE.jar;D:\RepMaven\repos\org\springframework\boot\spring-boot-starter-logging\1.5.9.RELEASE\spring-boot-starter-logging-1.5.9.RELEASE.jar;D:\RepMaven\repos\ch\qos\logback\logback-classic\1.1.11\logback-classic-1.1.11.jar;D:\RepMaven\repos\ch\qos\logback\logback-core\1.1.11\logback-core-1.1.11.jar;D:\RepMaven\repos\org\slf4j\jcl-over-slf4j\1.7.25\jcl-over-slf4j-1.7.25.jar;D:\RepMaven\repos\org\slf4j\jul-to-slf4j\1.7.25\jul-to-slf4j-1.7.25.jar;D:\RepMaven\repos\org\slf4j\log4j-over-slf4j\1.7.25\log4j-over-slf4j-1.7.25.jar;D:\RepMaven\repos\org\yaml\snakeyaml\1.17\snakeyaml-1.17.jar;D:\RepMaven\repos\org\springframework\boot\spring-boot-starter-tomcat\1.5.9.RELEASE\spring-boot-starter-tomcat-1.5.9.RELEASE.jar;D:\RepMaven\repos\org\apache\tomcat\embed\tomcat-embed-core\8.5.23\tomcat-embed-core-8.5.23.jar;D:\RepMaven\repos\org\apache\tomcat\tomcat-annotations-api\8.5.23\tomcat-annotations-api-8.5.23.jar;D:\RepMaven\repos\org\apache\tomcat\embed\tomcat-embed-el\8.5.23\tomcat-embed-el-8.5.23.jar;D:\RepMaven\repos\org\apache\tomcat\embed\tomcat-embed-websocket\8.5.23\tomcat-embed-websocket-8.5.23.jar;D:\RepMaven\repos\org\hibernate\hibernate-validator\5.3.6.Final\hibernate-validator-5.3.6.Final.jar;D:\RepMaven\repos\javax\validation\validation-api\1.1.0.Final\validation-api-1.1.0.Final.jar;D:\RepMaven\repos\org\jboss\logging\jboss-logging\3.3.1.Final\jboss-logging-3.3.1.Final.jar;D:\RepMaven\repos\com\fasterxml\classmate\1.3.4\classmate-1.3.4.jar;D:\RepMaven\repos\com\fasterxml\jackson\core\jackson-databind\2.8.10\jackson-databind-2.8.10.jar;D:\RepMaven\repos\com\fasterxml\jackson\core\jackson-annotations\2.8.0\jackson-annotations-2.8.0.jar;D:\RepMaven\repos\com\fasterxml\jackson\core\jackson-core\2.8.10\jackson-core-2.8.10.jar;D:\RepMaven\repos\org\springframework\spring-web\4.3.13.RELEASE\spring-web-4.3.13.RELEASE.jar;D:\RepMaven\repos\org\springframework\spring-aop\4.3.13.RELEASE\spring-aop-4.3.13.RELEASE.jar;D:\RepMaven\repos\org\springframework\spring-beans\4.3.13.RELEASE\spring-beans-4.3.13.RELEASE.jar;D:\RepMaven\repos\org\springframework\spring-context\4.3.13.RELEASE\spring-context-4.3.13.RELEASE.jar;D:\RepMaven\repos\org\springframework\spring-webmvc\4.3.13.RELEASE\spring-webmvc-4.3.13.RELEASE.jar;D:\RepMaven\repos\org\springframework\spring-expression\4.3.13.RELEASE\spring-expression-4.3.13.RELEASE.jar;D:\RepMaven\repos\org\slf4j\slf4j-api\1.7.25\slf4j-api-1.7.25.jar;D:\RepMaven\repos\org\springframework\spring-core\4.3.13.RELEASE\spring-core-4.3.13.RELEASE.jar com.njf.springboot.SpringBoot07RunApplication
准备开始创建IOC容器~~~
SpringApplicationRunListener...starting...
环境准备完毕
SpringApplicationRunListener...environmentPrepared..Windows 10

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.5.9.RELEASE)

IOC容器初始化~~
ApplicationContextInitializer...initialize...org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@365c30cc: startup date [Thu Jan 01 08:00:00 CST 1970]; root of context hierarchy
准备上下文 context
SpringApplicationRunListener...contextPrepared...
2021-12-20 19:08:49.269  INFO 520 --- [           main] c.n.s.SpringBoot07RunApplication         : Starting SpringBoot07RunApplication on niujifei with PID 520 (F:\My_Workspaceing\project\SpringBoot\spring-boot-07-run\target\classes started by niujifei in F:\My_Workspaceing\project\SpringBoot)
2021-12-20 19:08:49.274  INFO 520 --- [           main] c.n.s.SpringBoot07RunApplication         : No active profile set, falling back to default profiles: default
context 准备完毕
SpringApplicationRunListener...contextLoaded...
2021-12-20 19:08:49.336  INFO 520 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@365c30cc: startup date [Mon Dec 20 19:08:49 CST 2021]; root of context hierarchy
2021-12-20 19:08:50.860  INFO 520 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2021-12-20 19:08:50.868  INFO 520 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2021-12-20 19:08:50.870  INFO 520 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.23
2021-12-20 19:08:51.056  INFO 520 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2021-12-20 19:08:51.060  INFO 520 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1732 ms
2021-12-20 19:08:51.330  INFO 520 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Mapping servlet: 'dispatcherServlet' to [/]
2021-12-20 19:08:51.336  INFO 520 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2021-12-20 19:08:51.337  INFO 520 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2021-12-20 19:08:51.337  INFO 520 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2021-12-20 19:08:51.337  INFO 520 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2021-12-20 19:08:51.614  INFO 520 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@365c30cc: startup date [Mon Dec 20 19:08:49 CST 2021]; root of context hierarchy
2021-12-20 19:08:51.655  INFO 520 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2021-12-20 19:08:51.656  INFO 520 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2021-12-20 19:08:51.678  INFO 520 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2021-12-20 19:08:51.678  INFO 520 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2021-12-20 19:08:51.703  INFO 520 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2021-12-20 19:08:51.797  INFO 520 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2021-12-20 19:08:51.843  INFO 520 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
ApplicationRunner...run....
CommandLineRunner...run...[]
IOC容器创建完毕
SpringApplicationRunListener...finished...
2021-12-20 19:08:51.847  INFO 520 --- [           main] c.n.s.SpringBoot07RunApplication         : Started SpringBoot07RunApplication in 2.852 seconds (JVM running for 4.075)
原文地址:https://www.cnblogs.com/niujifei/p/15707360.html