SpringBoot2.0之SpringApplication源码分析

本文深入剖析了SpringBoot 2.0.1.RELEASE版本的启动流程,详细解读了从启动类到ConfigurableApplicationContext的创建过程,包括SpringApplication的run方法、SpringApplication构造方法、web应用类型判断、初始化器与监听器的加载、主类获取及run方法的具体执行步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

此源码分析针对于SpringBoot的2.0.1.RELEASE版本

一、首先我们先看到启动类中

在这里插入图片描述

二、点击进入SpringApplication的run方法

在这里插入图片描述
由此可以看出SpringApplication.run(AppWeiXin.class, args);实际上是返回的有对象的。即ConfigurableApplicationContext

三、继续进入run方法

在这里插入图片描述
由此我们可以知道

ConfigurableApplicationContext run = SpringApplication.run(AppWeiXin.class, args);
//其实就等于
ConfigurableApplicationContext run = new SpringApplication(AppWeiXin.class).run(args);
四、继续进入SpringApplication

在这里插入图片描述
可以知道,SpringApplication的有参构造方法再次调用了它的重载有参构造方法

五、然后我们看到上面大红框中的this.webApplicationType = deduceWebApplicationType();,进入deduceWebApplicationType方法

在这里插入图片描述
点击进入ClassUtil.isPresent方法中,同时进入REACTIVE_WEB_ENVIRONMENT_CLASS等几个常量中,我们可以知道deduceWebApplicationType就是判断是否为web应用,通过classLoader判断是否加载的有以下三个类

	public static final String DEFAULT_REACTIVE_WEB_CONTEXT_CLASS = "org.springframework."
			+ "boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext";

	private static final String REACTIVE_WEB_ENVIRONMENT_CLASS = "org.springframework."
			+ "web.reactive.DispatcherHandler";

	private static final String MVC_WEB_ENVIRONMENT_CLASS = "org.springframework."
			+ "web.servlet.DispatcherServlet";

然后我进入WebApplicationType中,看到NONE,SERVLET,REACTIVE三种枚举常量,查看官方文档官方文档可知:
在这里插入图片描述

六、看到四中的setInitializers((Collection)getSpringFactoriesInstances(ApplicationContextInitializer.class));

我们可以先看(Collection)getSpringFactoriesInstances(ApplicationContextInitializer.class),它其实就是从类路径下找到META-INF/spring.factories配置的所有ApplicationContextInitializer;然后再将其保存到List<ApplicationListener<?>>中
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

七、看到四中的setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));,原理同六

它是从类路径下找到META-INF/spring.factories配置的所有ApplicationListener

八、然后获取Main函数主类
this.mainApplicationClass = deduceMainApplicationClass();
九、SpringBoot的run方法说明
public ConfigurableApplicationContext run(String... args) {
 // 构造一个任务执行观察器
   StopWatch stopWatch = new StopWatch();
// 开始执行,记录开始时间
   stopWatch.start();
// 声明IOC容器
   ConfigurableApplicationContext context = null;
   Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
   configureHeadlessProperty();
// 获取SpringApplicationRunListeners,内部只有一个EventPublishingRunListener
   SpringApplicationRunListeners listeners = getRunListeners(args);
    //回调所有的获取SpringApplicationRunListener.starting()方法
 listeners.starting();
   try {
  // 构造一个应用程序参数持有类
      ApplicationArguments applicationArguments = new DefaultApplicationArguments(
            args);
  // 参数环境配置
      ConfigurableEnvironment environment = prepareEnvironment(listeners,
            applicationArguments);
      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, listeners, exceptionReporters, ex);
      throw new IllegalStateException(ex);
   }
   listeners.running(context);
   return context;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值