springboot启动过程源码分析

public ConfigurableApplicationContext run(String... args) {
    // 创建Startup实例,用于跟踪应用启动过程中的时间信息
    Startup startup = Startup.create();
    
    // 如果设置了注册关闭钩子,则启用添加关闭钩子的功能,确保应用可以优雅地关闭
    if (this.registerShutdownHook) {
        SpringApplication.shutdownHook.enableShutdownHookAddition();
    }
    
    // 创建引导上下文,它在创建Spring应用上下文之前提供了一个轻量级环境
    DefaultBootstrapContext bootstrapContext = createBootstrapContext();
    
    // 初始化ConfigurableApplicationContext为null,稍后会赋值
    ConfigurableApplicationContext context = null;
    
    // 配置无头属性,这对于一些不需要图形界面运行的应用程序是必要的
    configureHeadlessProperty();
    
    // 获取并初始化监听器,它们会在应用生命周期的关键点被通知
    SpringApplicationRunListeners listeners = getRunListeners(args);
    
    // 通知所有监听器应用程序即将开始启动
    listeners.starting(bootstrapContext, this.mainApplicationClass);
    
    try {
        // 创建应用参数对象,包含命令行参数
        ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
        
        // 准备环境配置,包括属性源、配置文件等
        ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
        
        // 打印banner,通常是一个ASCII艺术文本,显示在控制台,标识应用程序名称和版本
        Banner printedBanner = printBanner(environment);
        
        // 创建应用上下文(容器),这是Spring管理Bean的核心
        context = createApplicationContext();
        
        // 设置应用启动信息追踪器
        context.setApplicationStartup(this.applicationStartup);
        
        // 准备上下文,设置环境、监听器等
        prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
        
        // 刷新上下文,初始化所有单例bean
        refreshContext(context);
        
        // 在刷新上下文之后进行额外的处理
        afterRefresh(context, applicationArguments);
        
        // 记录应用启动完成的时间信息
        startup.started();
        
        // 如果启用了日志记录,则记录启动时间和其它相关信息
        if (this.logStartupInfo) {
            new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), startup);
        }
        
        // 通知所有监听器应用已启动
        listeners.started(context, startup.timeTakenToStarted());
        
        // 调用实现了ApplicationRunner或CommandLineRunner接口的beans
        callRunners(context, applicationArguments);
    } catch (Throwable ex) {
        // 捕获任何异常并进行相应的处理,确保在出错时能正确地清理资源
        throw handleRunFailure(context, ex, listeners);
    }
    
    try {
        // 如果应用上下文正在运行,则通知所有监听器应用已准备好
        if (context.isRunning()) {
            listeners.ready(context, startup.ready());
        }
    } catch (Throwable ex) {
        // 处理可能发生的异常,保证应用的健壮性
        throw handleRunFailure(context, ex, null);
    }
    
    // 返回准备好的应用上下文
    return context;
}
public void refresh() throws BeansException, IllegalStateException {
    // 获取锁以确保线程安全
    this.startupShutdownLock.lock();
    try {
        // 记录当前正在执行刷新操作的线程
        this.startupShutdownThread = Thread.currentThread();

        // 开始记录上下文刷新的启动步骤
        StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

        // 准备上下文以进行刷新,包括设置启动时间、激活标志等
        prepareRefresh();

        // 通知子类刷新内部 Bean 工厂,并获取一个新的 Bean 工厂实例
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // 准备 Bean 工厂以便在当前上下文中使用,包括设置类加载器、属性编辑器等
        prepareBeanFactory(beanFactory);

        try {
            // 允许子类对 Bean 工厂进行后处理
            postProcessBeanFactory(beanFactory);

            // 开始记录 Bean 后处理的启动步骤
            StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
            
            // 调用所有注册的 Bean 工厂后处理器(BeanFactoryPostProcessor),允许它们修改 Bean 定义
            invokeBeanFactoryPostProcessors(beanFactory);
            
            // 注册所有 Bean 后处理器(BeanPostProcessor),这些处理器会在 Bean 实例化前后进行拦截处理
            registerBeanPostProcessors(beanFactory);
            
            // 结束 Bean 后处理的记录步骤
            beanPostProcess.end();

            // 初始化消息源(MessageSource)用于国际化支持
            initMessageSource();

            // 初始化应用事件广播器(ApplicationEventMulticaster)用于发布应用事件
            initApplicationEventMulticaster();

            // 初始化其他特殊的 Bean,具体实现由子类决定
            onRefresh();

            // 注册监听器,以便在适当的时候接收事件通知
            registerListeners();

            // 实例化所有非延迟初始化的单例 Bean
            finishBeanFactoryInitialization(beanFactory);

            // 最后一步:发布上下文刷新完成事件
            finishRefresh();
        }
        catch (RuntimeException | Error ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
            }

            // 销毁已经创建的单例 Bean 以避免资源泄露
            destroyBeans();

            // 重置 'active' 标志
            cancelRefresh(ex);

            // 将异常传播给调用者
            throw ex;
        }
        finally {
            // 结束上下文刷新的记录步骤
            contextRefresh.end();
        }
    }
    finally {
        // 清除当前正在执行刷新操作的线程
        this.startupShutdownThread = null;
        
        // 解锁以允许其他线程进行刷新操作
        this.startupShutdownLock.unlock();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值