springboot启动过程

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();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值