【附录】Spring容器的启动过程是怎样的?

此文是【Spring 容器详解】的支节点。

概述

容器启动,其实都是基于main方法的。不同的容器实现类,读取bean的方式不同,但最终都要通过AbstractApplicationContext.refresh()方法完成的;即刷新容器,刷新容器有12个核心步骤。理解这个流程对于深入理解Spring的工作原理非常重要。

注意:这里需要理解在这个方法里面都做了些什么,并不需要死记硬背,在适当的情况下进行debug,或理解与其他jar包集成有很大帮助作用。

refresh()方法的核心流程

java 复制代码
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // 1. 准备刷新
        prepareRefresh();
        
        // 2. 获取BeanFactory
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        
        // 3. 准备BeanFactory
        prepareBeanFactory(beanFactory);
        
        try {
            // 4. 允许子类在标准初始化后修改BeanFactory
            postProcessBeanFactory(beanFactory);
            
            // 5. 调用BeanFactoryPostProcessor
            invokeBeanFactoryPostProcessors(beanFactory);
            
            // 6. 注册BeanPostProcessor
            registerBeanPostProcessors(beanFactory);
            
            // 7. 初始化消息源
            initMessageSource();
            
            // 8. 初始化事件广播器
            initApplicationEventMulticaster();
            
            // 9. 初始化特定上下文子类中的其他特殊bean
            onRefresh();
            
            // 10. 注册监听器
            registerListeners();
            
            // 11. 实例化所有非懒加载的单例Bean
            finishBeanFactoryInitialization(beanFactory);
            
            // 12. 完成刷新
            finishRefresh();
        } catch (BeansException ex) {
            // 清理资源
            destroyBeans();
            cancelRefresh(ex);
            throw ex;
        } finally {
            // 重置Spring通用的内省缓存
            resetCommonCaches();
        }
    }
}

详细步骤解析

步骤1: prepareRefresh() - 准备刷新

java 复制代码
protected void prepareRefresh() {
    // 设置启动时间
    this.startupDate = System.currentTimeMillis();
    this.closed.set(false);
    this.active.set(true);
    
    // 初始化属性源
    initPropertySources();
    
    // 验证必需的属性
    getEnvironment().validateRequiredProperties();
    
    // 存储早期ApplicationListeners
    this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}

主要功能:

  • 设置容器的启动状态
  • 初始化属性源
  • 验证必需的属性
  • 准备早期事件监听器

步骤2: obtainFreshBeanFactory() - 获取BeanFactory

java 复制代码
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    refreshBeanFactory();
    return getBeanFactory();
}

protected final void refreshBeanFactory() throws BeansException {
    if (hasBeanFactory()) {
        destroyBeans();
        closeBeanFactory();
    }
    try {
        // 创建新的BeanFactory
        DefaultListableBeanFactory beanFactory = createBeanFactory();
        beanFactory.setSerializationId(getId());
        customizeBeanFactory(beanFactory);
        loadBeanDefinitions(beanFactory);
        this.beanFactory = beanFactory;
    } catch (IOException ex) {
        throw new ApplicationContextException("I/O error parsing bean definition source", ex);
    }
}

主要功能:

  • 创建新的BeanFactory实例
  • 自定义BeanFactory配置
  • 加载BeanDefinition

步骤3: prepareBeanFactory() - 准备BeanFactory

java 复制代码
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 设置类加载器
    beanFactory.setBeanClassLoader(getClassLoader());
    
    // 设置表达式解析器
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    
    // 设置属性编辑器注册器
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    
    // 添加ApplicationContextAwareProcessor
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    
    // 忽略依赖接口
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    
    // 注册依赖
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);
    
    // 添加ApplicationListenerDetector
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
    
    // 添加LoadTimeWeaverAwareProcessor
    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
    }
    
    // 设置临时类加载器
    if (!beanFactory.hasTempClassLoader()) {
        beanFactory.setTempClassLoader(getTempClassLoader());
    }
    
    // 注册环境Bean
    if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
        beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
        beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
        beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    }
}

主要功能:

  • 设置类加载器、表达式解析器等基础设施
  • 注册各种Aware接口的处理器
  • 注册可解析的依赖
  • 注册环境相关的Bean

步骤4: postProcessBeanFactory() - 后处理BeanFactory

java 复制代码
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 子类可以重写此方法,在标准初始化后修改BeanFactory
    // 例如:WebApplicationContext会在这里注册ServletContextAwareProcessor
}

主要功能:

  • 允许子类在标准初始化后修改BeanFactory
  • WebApplicationContext会在这里注册Web相关的处理器

步骤5: invokeBeanFactoryPostProcessors() - 调用BeanFactoryPostProcessor

java 复制代码
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
}

执行顺序:

  1. BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()
  2. BeanDefinitionRegistryPostProcessor.postProcessBeanFactory()
  3. BeanFactoryPostProcessor.postProcessBeanFactory()

主要功能:

  • 处理配置类(@Configuration)
  • 处理属性占位符
  • 注册自定义作用域
  • 条件化Bean注册

步骤6: registerBeanPostProcessors() - 注册BeanPostProcessor

java 复制代码
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

注册的BeanPostProcessor类型:

  • PriorityOrdered - 最高优先级
  • Ordered - 普通优先级
  • 普通BeanPostProcessor - 默认优先级

主要功能:

  • 注册各种BeanPostProcessor
  • 按优先级排序
  • 为后续Bean实例化做准备

步骤7: initMessageSource() - 初始化消息源

java 复制代码
protected void initMessageSource() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
        this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
        if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
            HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
            if (hms.getParentMessageSource() == null) {
                hms.setParentMessageSource(getInternalParentMessageSource());
            }
        }
    } else {
        // 创建默认的MessageSource
        DelegatingMessageSource dms = new DelegatingMessageSource();
        dms.setParentMessageSource(getInternalParentMessageSource());
        this.messageSource = dms;
        beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
    }
}

主要功能:

  • 初始化国际化消息源
  • 支持消息的国际化处理

步骤8: initApplicationEventMulticaster() - 初始化事件广播器

java 复制代码
protected void initApplicationEventMulticaster() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
        this.applicationEventMulticaster = beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
    } else {
        // 创建默认的事件广播器
        this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
    }
}

主要功能:

  • 初始化事件广播器
  • 为Spring事件机制做准备

步骤9: onRefresh() - 初始化特定上下文

java 复制代码
protected void onRefresh() throws BeansException {
    // 子类可以重写此方法,初始化特定上下文中的其他特殊bean
    // 例如:WebApplicationContext会在这里初始化主题源
}

主要功能:

  • 允许子类初始化特定的Bean
  • WebApplicationContext会在这里初始化主题源

步骤10: registerListeners() - 注册监听器

java 复制代码
protected void registerListeners() {
    // 注册静态指定的监听器
    for (ApplicationListener<?> listener : getApplicationListeners()) {
        getApplicationEventMulticaster().addApplicationListener(listener);
    }
    
    // 注册BeanFactory中的监听器
    String[] listenerBeanNames = getBeanFactory().getBeanNamesForType(ApplicationListener.class, true, false);
    for (String listenerBeanName : listenerBeanNames) {
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }
    
    // 发布早期事件
    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    this.earlyApplicationEvents = null;
    if (earlyEventsToProcess != null) {
        for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
            getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }
}

主要功能:

  • 注册ApplicationListener
  • 处理早期事件

步骤11: finishBeanFactoryInitialization() - 完成BeanFactory初始化

java 复制代码
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // 初始化转换服务
    if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
            beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
        beanFactory.setConversionService(
                beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
    }
    
    // 注册嵌入值解析器
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
            @Override
            public String resolveStringValue(String strVal) {
                return getEnvironment().resolvePlaceholders(strVal);
            }
        });
    }
    
    // 初始化LoadTimeWeaverAware Bean
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }
    
    // 停止使用临时类加载器
    beanFactory.setTempClassLoader(null);
    
    // 冻结所有Bean定义
    beanFactory.freezeConfiguration();
    
    // 实例化所有非懒加载的单例Bean
    beanFactory.preInstantiateSingletons();
}

核心方法:preInstantiateSingletons()

java 复制代码
public void preInstantiateSingletons() throws BeansException {
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
    
    // 触发所有非懒加载单例Bean的初始化
    for (String beanName : beanNames) {
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            if (isFactoryBean(beanName)) {
                // 处理FactoryBean
                Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                if (bean instanceof FactoryBean) {
                    FactoryBean<?> factory = (FactoryBean<?>) bean;
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged(
                                (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
                                getAccessControlContext());
                    } else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                ((SmartFactoryBean<?>) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        getBean(beanName);
                    }
                }
            } else {
                // 处理普通Bean
                getBean(beanName);
            }
        }
    }
    
    // 触发所有单例Bean的SmartInitializingSingleton回调
    for (String beanName : beanNames) {
        Object singletonInstance = getSingleton(beanName);
        if (singletonInstance instanceof SmartInitializingSingleton) {
            SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                    smartSingleton.afterSingletonsInstantiated();
                    return null;
                }, getAccessControlContext());
            } else {
                smartSingleton.afterSingletonsInstantiated();
            }
        }
    }
}

主要功能:

  • 实例化所有非懒加载的单例Bean
  • 处理FactoryBean
  • 触发SmartInitializingSingleton回调

步骤12: finishRefresh() - 完成刷新

java 复制代码
protected void finishRefresh() {
    // 清除资源缓存
    clearResourceCaches();
    
    // 初始化生命周期处理器
    initLifecycleProcessor();
    
    // 获取生命周期处理器并启动所有实现了Lifecycle接口的Bean
    getLifecycleProcessor().onRefresh();
    
    // 发布ContextRefreshedEvent事件
    publishEvent(new ContextRefreshedEvent(this));
    
    // 参与LiveBeansView MBean
    LiveBeansView.registerApplicationContext(this);
}

主要功能:

  • 清理资源缓存
  • 初始化生命周期处理器
  • 启动Lifecycle Bean
  • 发布ContextRefreshedEvent事件

总结

Spring的refresh()方法包含了容器初始化的完整流程,这12个步骤确保了:

  1. 环境准备 - 设置启动状态、验证属性
  2. 基础设施搭建 - 创建BeanFactory、设置各种处理器
  3. 配置处理 - 处理BeanFactoryPostProcessor、注册BeanPostProcessor
  4. 事件机制 - 初始化消息源、事件广播器
  5. Bean实例化 - 创建所有非懒加载的单例Bean
  6. 完成启动 - 发布事件、启动生命周期组件

理解这个流程对于:

  • 调试Spring应用启动问题
  • 理解Spring的扩展机制
  • 优化应用启动性能
  • 自定义Spring容器行为

都非常重要。

相关推荐
Olrookie39 分钟前
若依前后端分离版学习笔记(五)——Spring Boot简介与Spring Security
笔记·后端·学习·spring·ruoyi
小白的代码日记1 小时前
基于 Spring Boot 的小区人脸识别与出入记录管理系统实现
java·spring boot·后端
Chaney不会代码1 小时前
Java7/8中的HashMap深挖
后端
新程快咖员1 小时前
兄弟们,你们安装IDEA 2025.2了吗?java编辑器代码提示失效?临时解决方案新鲜出炉!
后端·intellij idea
调试人生的显微镜1 小时前
移动端网页调试实战,跨设备兼容与触控交互问题排查全流程
后端
onejason2 小时前
《PHP 爬虫实战指南:获取淘宝店铺详情》
前端·后端·php
码事漫谈2 小时前
你的代码可能在偷偷崩溃!
后端
白应穷奇2 小时前
编写高性能数据处理代码 02
后端·python
这个做不了2 小时前
基于模板方法与工厂模式的多支付公司/产品接入方案
后端