springboot启动过程
1、运行启动类的main方法,执行SpringApplication.run
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
1.1、初始化SpringApplication,执行构造函数。
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.sources = new LinkedHashSet();
this.bannerMode = Mode.CONSOLE;
this.logStartupInfo = true;
this.addCommandLineProperties = true;
this.addConversionService = true;
this.headless = true;
this.registerShutdownHook = true;
this.additionalProfiles = new HashSet();
this.isCustomEnvironment = false;
this.lazyInitialization = false;
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
//确定程序类型 例如枚举SERVLET
this.webApplicationType = WebApplicationType.deduceFromClasspath();
//加载所有的初始化器
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
//加载所有的监听器
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
//设置程序运行的主类
this.mainApplicationClass = this.deduceMainApplicationClass();
}
Spring
Boot中的ApplicationContextInitializer是一个接口,用于在应用程序上下文创建之前自定义应用程序上下文。它主要用于在ApplicationContext创建之前对ApplicationContext的属性进行配置,例如设置特定的系统属性、环境变量、上下文参数等。
ApplicationContextInitializer可以被用来向ApplicationContext添加属性源、bean定义、配置类以及其他的上下文设置。通过实现ApplicationContextInitializer接口,可以在应用程序启动期间进行一些基础的配置,以确保应用程序在启动时处于最佳状态。此外,该接口还可以与Spring
Boot的其他功能一起使用,如自动配置,来定制应用程序的行为。
Spring Boot中的ApplicationListener是用于监听Spring Boot应用程序中发生的事件的接口。ApplicationListener提供了一种机制,可以在应用程序启动、停止、上下文刷新、上下文关闭等事件发生时执行一些特定操作。
在Spring
Boot应用程序中,可以通过实现ApplicationListener接口并覆盖相应的方法来监听事件。例如,可以实现ApplicationListener接口来监听应用程序上下文刷新事件,并在上下文刷新完成后执行一些初始化操作。Spring
Boot提供了许多内置的事件,如ApplicationStartedEvent、ApplicationReadyEvent、ApplicationFailedEvent、ContextRefreshedEvent、ContextStartedEvent、ContextStoppedEvent和ContextClosedEvent等。这些事件可以帮助开发人员更好地管理应用程序的生命周期和状态。通过使用ApplicationListener,在Spring
Boot应用程序中可以实现更加灵活、高效和可扩展的事件处理机制,从而提高应用程序的可维护性和可靠性。
2、执行run方法
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
this.configureHeadlessProperty();
//获取并启用监听器
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting();
Collection exceptionReporters;
try {
//设置应用程序参数
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
//准备环境变量
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
//忽略bean信息
this.configureIgnoreBeanInfo(environment);
//打印banner信息
Banner printedBanner = this.printBanner(environment);
//创建应用程序的上下文
context = this.createApplicationContext();
//实例化异常报告
exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
//准备上下文环境
this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
//刷新上下文
this.refreshContext(context);
this.afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
}
//发布上下文准备就绪事件
listeners.started(context);
//执行自定义的run方法
this.callRunners(context, applicationArguments);
} catch (Throwable var10) {
this.handleRunFailure(context, var10, exceptionReporters, listeners);
throw new IllegalStateException(var10);
}
try {
listeners.running(context);
return context;
} catch (Throwable var9) {
this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var9);
}
}
SpringApplicationRunListener是SpringBoot中的一个监听器接口,用于监听Spring应用程序的生命周期事件。它可以在Spring应用程序启动、准备、运行和关闭时执行一些自定义操作,例如:
1、在应用程序启动前,可以做一些初始化操作,例如加载配置文件等。
2、在应用程序启动后,可以做一些监控或日志记录等操作,例如记录应用程序启动时间等。
3、在应用程序关闭前,可以做一些清理工作,例如释放资源等。
4、在应用程序关闭后,可以做一些统计或日志记录等操作,例如记录应用程序运行时间等。
通过自定义实现SpringApplicationRunListener接口并注册到Spring应用程序中,可以扩展SpringBoot的功能,实现更加灵活的应用程序配置和管理。
EventPublishingRunListener 是 Spring Boot 应用程序的监听器,用于在应用程序启动期间发布各种事件。它主要是通过 ApplicationEventPublisher 接口来发布事件,这些事件可以是 Spring Boot 内置的事件,也可以是自定义事件。EventPublishingRunListener
的作用是帮助开发者在应用程序启动时,发布多种类型的事件,以便其他组件可以监听并处理这些事件。这些事件可以包括应用程序启动、上下文加载、bean加载、Web 服务器启动等等。EventPublishingRunListener
的另一个重要作用是帮助开发者在应用程序启动时,处理事件,以便实现一些特殊的逻辑。比如,在应用程序启动时,可以使用
EventPublishingRunListener 来初始化一些数据,或者在应用程序关闭时,使用
EventPublishingRunListener 来清理一些资源。
prepareContext方法,它的作用是准备应用程序运行时的上下文环境。
具体来说,prepareContext方法会创建一个ApplicationContext对象,该对象包含了应用程序中所有需要加载的bean、配置文件、组件等信息。这些信息是通过读取classpath下的配置文件或者通过注解等方式来获取的。
在prepareContext方法中,还会进行一些必要的配置,例如注册一些默认的bean和组件,设置一些系统属性等。
总的来说,prepareContext方法的作用是为应用程序的运行提供一个完整的上下文环境,以便应用程序能够正常地运行。
2.1、refreshContext
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing. 准备刷新上下文
prepareRefresh();
// Tell the subclass to refresh the internal bean factory. 告诉子类刷新内部bean工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context. 准备bean工厂以用于此上下文
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses. 允许在上下文子类中对bean工厂进行后置处理
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context. 调用上下文中注册为bean的工厂处理器
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation. 注册拦截器bean创建的bean处理器
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// Initialize message source for this context. 初始化此上下文的消息源
initMessageSource();
// Initialize event multicaster for this context. 为此上下文初始化事件多播
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses. 初始化特定上下文子类中的其他特殊bean
onRefresh();
// Check for listener beans and register them. 检查监听器bean并注册
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons. 实例化所有剩余的(非懒惰初始化)单例
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event. 最后一步:发布相应的事件
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources. 销毁已创建的单例以避免悬空资源
destroyBeans();
// Reset 'active' flag. 重置active标志
cancelRefresh(ex);
// Propagate exception to caller. 将异常传播到调用方
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
//重置Spring核心中的公共内省缓存,因为我们可能不再需要单例bean的元数据
resetCommonCaches();
contextRefresh.end();
}
}
}