一、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)回调容器中所有的ApplicationRunner、 CommandLineRunner的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)