Spring IoC 容器启动深度解析:从源码到设计的完整链路

 

🎯 这篇文章写给谁:3年以上Java开发,想彻底搞懂Spring容器启动机制,不只是背步骤,更要理解设计思想与源码实现。

🔍 开场:面试题背后的真实意图

面试官问“Spring容器启动流程”,表面是考流程,实际是考:

  1. 架构设计能力:Spring如何解耦配置、解析、实例化?
  2. 源码阅读能力:关键类(如DefaultListableBeanFactory)的职责与协作?
  3. 扩展思维:在哪里可以插入自定义逻辑?
  4. 问题排查能力:Bean创建失败,如何定位到具体阶段?

这篇文章,我们从 源码、设计、性能、扩展 四个维度,彻底拆解Spring容器的启动过程。


🧠 第一部分:核心架构与设计思想

1.1 三层架构模型

Spring容器的设计遵循三层架构,每层职责清晰:

层次 核心接口/类 职责 设计模式
配置层 ResourceResourceLoader 统一抽象各种配置源 策略模式
定义层 BeanDefinitionBeanDefinitionRegistry 描述Bean元数据,支持动态注册 元数据模式
实例层 BeanFactoryApplicationContext 管理Bean生命周期,提供企业级功能 工厂模式、模板方法

关键洞察:Spring没有直接操作XML或注解,而是通过中间层BeanDefinition实现配置与实现的解耦。

1.2 BeanFactory vs ApplicationContext:不只是继承关系

// ApplicationContext 是 BeanFactory 的子接口,但增加了更多企业级功能
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, 
                                          HierarchicalBeanFactory, MessageSource,
                                          ApplicationEventPublisher, ResourcePatternResolver {
    // ... 更多功能
}

核心区别表

特性 BeanFactory ApplicationContext
Bean实例化时机 懒加载(调用getBean时) 预加载(容器启动时)
国际化支持 ❌ 不支持 ✅ 支持(MessageSource)
事件机制 ❌ 不支持 ✅ 支持(ApplicationEventPublisher)
AOP集成 ❌ 需要额外配置 ✅ 自动集成
资源加载 ❌ 基础ResourceLoader ✅ ResourcePatternResolver

设计思想ApplicationContext通过组合模式,在BeanFactory基础上增加了企业级功能,实现了“单一职责”原则。


🔬 第二部分:refresh() 方法的13个步骤深度源码分析

源码位置org.springframework.context.support.AbstractApplicationContext.refresh()

这是容器启动的“总纲”,我们逐行分析:

步骤1:prepareRefresh() – 容器刷新准备

protected void prepareRefresh() {
    this.startupDate = System.currentTimeMillis();
    this.closed.set(false);
    this.active.set(true);
    
    // 初始化占位符配置
    initPropertySources();
    
    // 验证必要的环境属性
    getEnvironment().validateRequiredProperties();
    
    // 早期事件监听器
    this.earlyApplicationEvents = new LinkedHashSet<>();
}

深度分析

  • initPropertySources()扩展点,子类可以重写,从配置中心加载配置
  • validateRequiredProperties():确保必要配置存在,否则抛出IllegalStateException
  • 使用AtomicBoolean保证并发安全,容器状态可变但线程安全

步骤2:obtainFreshBeanFactory() – 获取BeanFactory

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    // 刷新BeanFactory(对于AbstractRefreshableApplicationContext)
    refreshBeanFactory();
    
    // 获取新创建的BeanFactory
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    
    // 返回
    return beanFactory;
}

关键源码AbstractRefreshableApplicationContext.refreshBeanFactory()

protected final void refreshBeanFactory() throws BeansException {
    // 如果已有BeanFactory,先销毁
    if (hasBeanFactory()) {
        destroyBeans();
        closeBeanFactory();
    }
    
    try {
        // 创建新的DefaultListableBeanFactory
        DefaultListableBeanFactory beanFactory = createBeanFactory();
        
        // 设置序列化ID(用于分布式环境)
        beanFactory.setSerializationId(getId());
        
        // 定制BeanFactory(设置是否允许循环依赖、覆盖等)
        customizeBeanFactory(beanFactory);
        
        // 加载BeanDefinition(委托给子类实现)
        loadBeanDefinitions(beanFactory);
        
        // 设置到上下文
        this.beanFactory = beanFactory;
    }
    catch (IOException ex) {
        throw new ApplicationContextException("I/O error parsing bean definition", ex);
    }
}

设计亮点

  1. 销毁重建模式:每次刷新都是全新BeanFactory,避免状态污染
  2. 模板方法loadBeanDefinitions()由子类实现(XML、注解等不同方式)
  3. 序列化支持:为分布式缓存、会话复制预留接口

步骤3:prepareBeanFactory(beanFactory) – 准备BeanFactory

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 设置ClassLoader
    beanFactory.setBeanClassLoader(getClassLoader());
    
    // 设置表达式解析器(支持SpEL)
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    
    // 设置属性编辑器注册器
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    
    // 添加BeanPostProcessor:ApplicationContextAwareProcessor
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    
    // 忽略Aware接口的自动装配(由上面的Processor处理)
    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等)
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);
    
    // 添加BeanPostProcessor:ApplicationListenerDetector
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
    
    // 添加LoadTimeWeaver(AspectJ LTW支持)
    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
    
    // 注册环境相关的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());
    }
}

深度分析

  1. Aware接口处理机制:通过ApplicationContextAwareProcessor统一处理,避免每个Bean都实现注入逻辑
  2. 可解析依赖注册BeanFactoryApplicationContext等作为特殊依赖,直接从容器获取,不通过常规注入
  3. 环境Bean注册Environment、系统属性等作为单例Bean注册,全局可用

步骤4:postProcessBeanFactory(beanFactory) – BeanFactory后置处理

扩展点:子类可以重写,在BeanFactory准备完成后、BeanDefinition加载前进行定制。

典型用例WebApplicationContext在这里注册ServletContext相关的Bean。

// 例如:GenericWebApplicationContext的实现
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 添加ServletContextAwareProcessor
    beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
    
    // 忽略ServletContextAware等接口的自动装配
    beanFactory.ignoreDependencyInterface(ServletContextAware.class);
    beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
}

设计思想:通过钩子方法,允许不同应用场景(Web、非Web)定制容器行为。

步骤5:invokeBeanFactoryPostProcessors(beanFactory) – 执行BeanFactoryPostProcessor

这是最重要的扩展点之一,可以修改BeanDefinition。

源码跟踪:调用链为refresh()invokeBeanFactoryPostProcessors()PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()

public static void invokeBeanFactoryPostProcessors(
        ConfigurableListableBeanFactory beanFactory, 
        List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
    Set<String> processedBeans = new HashSet<>();
    
    // 1. 处理实现了PriorityOrdered接口的BeanFactoryPostProcessor
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, truefalse);
    List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    
    for (String ppName : postProcessorNames) {
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            processedBeans.add(ppName);
        }
    }
    
    // 排序并执行
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    
    // 2. 处理实现了Ordered接口的(类似逻辑)
    // 3. 处理其他的(类似逻辑)
    
    // 4. 处理BeanDefinitionRegistryPostProcessor(特殊的BeanFactoryPostProcessor)
    // 可以注册新的BeanDefinition
}

实战案例PropertySourcesPlaceholderConfigurer

// 处理 ${...} 占位符
public class PropertySourcesPlaceholderConfigurer implements BeanFactoryPostProcessor, EnvironmentAware {
    
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        // 获取所有BeanDefinition
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        String[] beanNames = registry.getBeanDefinitionNames();
        
        for (String beanName : beanNames) {
            BeanDefinition bd = registry.getBeanDefinition(beanName);
            
            // 解析占位符
            resolvePlaceholders(bd.getPropertyValues());
            resolvePlaceholders(bd.getConstructorArgumentValues());
        }
    }
}

性能考量

  1. BeanFactoryPostProcessor容器启动阶段执行,会影响启动时间
  2. 执行顺序通过PriorityOrderedOrdered接口控制,避免循环依赖
  3. 实现时要考虑最小化影响,避免全量扫描所有BeanDefinition

步骤6:registerBeanPostProcessors(beanFactory) – 注册BeanPostProcessor

BeanPostProcessor影响Bean的创建过程,在实例化前后执行。

源码分析:与步骤5类似,但只注册不执行(执行在Bean创建时)。

// 注册顺序同样受PriorityOrdered、Ordered控制
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, truefalse);
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();

// 分类
for (String ppName : postProcessorNames) {
    if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
        priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanPostProcessor.class));
    }
    else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
        orderedPostProcessorNames.add(ppName);
    }
    else {
        nonOrderedPostProcessorNames.add(ppName);
    }
}

// 排序并注册
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// ... 注册ordered和非ordered的

重要BeanPostProcessor

类名 作用 执行时机
AutowiredAnnotationBeanPostProcessor 处理@Autowired@Value 属性填充前
CommonAnnotationBeanPostProcessor 处理@Resource@PostConstruct 初始化前后
ApplicationListenerDetector 检测ApplicationListener Bean 初始化后
AsyncAnnotationBeanPostProcessor 处理@Async 初始化后

设计模式责任链模式,多个BeanPostProcessor按顺序执行。

步骤7:initMessageSource() – 初始化国际化

源码AbstractApplicationContext.initMessageSource()

protected void initMessageSource() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    
    // 检查是否已定义名为"messageSource"的Bean
    if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
        // 获取并设置
        MessageSource messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
        
        // 如果当前上下文有父上下文,且messageSource是HierarchicalMessageSource
        if (this.parent != null && messageSource instanceof HierarchicalMessageSource) {
            HierarchicalMessageSource hms = (HierarchicalMessageSource) messageSource;
            if (hms.getParentMessageSource() == null) {
                hms.setParentMessageSource(getInternalParentMessageSource());
            }
        }
    }
    else {
        // 创建默认的DelegatingMessageSource
        DelegatingMessageSource dms = new DelegatingMessageSource();
        dms.setParentMessageSource(getInternalParentMessageSource());
        beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, dms);
    }
}

设计思想懒加载模式,只有需要国际化时才初始化。

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

源码AbstractApplicationContext.initApplicationEventMulticaster()

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 {
        // 默认的SimpleApplicationEventMulticaster
        this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, 
                                     this.applicationEventMulticaster);
    }
}

并发安全SimpleApplicationEventMulticaster使用ConcurrentHashMap存储监听器,支持并发注册。

步骤9:onRefresh() – 容器刷新扩展点

扩展点:子类可以重写,在Bean实例化前执行特定逻辑。

典型用例

  • WebApplicationContext:初始化主题资源
  • ReactiveWebApplicationContext:初始化Reactive服务器
// 例如:ServletWebServerApplicationContext
protected void onRefresh() {
    super.onRefresh();
    
    try {
        // 创建Web服务器
        createWebServer();
    }
    catch (Throwable ex) {
        throw new ApplicationContextException("Unable to start web server", ex);
    }
}

设计模式模板方法,允许不同场景定制启动逻辑。

步骤10:registerListeners() – 注册事件监听器

源码AbstractApplicationContext.registerListeners()

protected void registerListeners() {
    // 1. 注册静态指定的监听器(通过addApplicationListener添加的)
    for (ApplicationListener<?> listener : getApplicationListeners()) {
        getApplicationEventMulticaster().addApplicationListener(listener);
    }
    
    // 2. 注册BeanFactory中定义的所有ApplicationListener Bean
    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, truefalse);
    for (String listenerBeanName : listenerBeanNames) {
        getApplicationEventMulticaster().addApplicationListener(
            new ApplicationListenerBeanAdapter(listenerBeanName));
    }
    
    // 3. 发布早期事件(在监听器注册之前发生的事件)
    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    this.earlyApplicationEvents = null;
    if (earlyEventsToProcess != null) {
        for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
            getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }
}

设计亮点

  1. 早期事件处理:解决“先有事件还是先有监听器”的时序问题
  2. 适配器模式ApplicationListenerBeanAdapter包装Bean,延迟获取实例

步骤11:finishBeanFactoryInitialization(beanFactory) – 初始化所有单例Bean

这是最核心、最耗时的步骤,所有非懒加载的单例Bean在这里实例化。

源码跟踪refresh()finishBeanFactoryInitialization()beanFactory.preInstantiateSingletons()

// DefaultListableBeanFactory.preInstantiateSingletons()
public void preInstantiateSingletons() throws BeansException {
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
    
    // 遍历所有Bean定义
    for (String beanName : beanNames) {
        RootBeanDefinition bd = getMergedBeanDefinition(beanName);
        
        // 只处理单例、非抽象、非懒加载的Bean
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            // 如果是FactoryBean,特殊处理
            if (isFactoryBean(beanName)) {
                FactoryBean<?> factoryBean = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
                // ... FactoryBean逻辑
            }
            else {
                // 🔥 核心:调用getBean()触发Bean创建
                getBean(beanName);
            }
        }
    }
    
    // 所有单例Bean创建完成后,执行回调
    for (String beanName : beanNames) {
        Object singletonInstance = getSingleton(beanName);
        if (singletonInstance instanceof SmartInitializingSingleton) {
            SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
            smartSingleton.afterSingletonsInstantiated();
        }
    }
}

getBean()的调用链路

AbstractBeanFactory.getBean()
    ↓
AbstractBeanFactory.doGetBean()
    ↓
DefaultSingletonBeanRegistry.getSingleton() // 尝试从缓存获取
    ↓
AbstractAutowireCapableBeanFactory.createBean() // 缓存没有,开始创建
    ↓
AbstractAutowireCapableBeanFactory.doCreateBean() // 真正的创建逻辑
    ↓
  instantiateBean() // 实例化
  populateBean()    // 属性注入
  initializeBean()  // 初始化

深度分析

  1. 三级缓存解决循环依赖:在doCreateBean()中,Bean实例化后立即放入三级缓存
  2. AOP代理:如果有必要,在初始化后阶段创建代理对象
  3. 生命周期回调@PostConstructInitializingBeaninit-method按顺序执行

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

源码AbstractApplicationContext.finishRefresh()

protected void finishRefresh() {
    // 1. 清除资源缓存(如果有)
    clearResourceCaches();
    
    // 2. 初始化生命周期处理器
    initLifecycleProcessor();
    
    // 3. 启动生命周期处理器(触发Lifecycle.start())
    getLifecycleProcessor().onRefresh();
    
    // 4. 发布ContextRefreshedEvent事件
    publishEvent(new ContextRefreshedEvent(this));
    
    // 5. 注册到LiveBeansView(JMX监控)
    LiveBeansView.registerApplicationContext(this);
}

设计思想事件驱动架构,容器状态变化通过事件通知相关组件。

步骤13:resetCommonCaches() – 重置公共缓存

性能优化:清理启动过程中使用的临时缓存,减少内存占用。

protected void resetCommonCaches() {
    ReflectionUtils.clearCache();
    ResolvableType.clearCache();
    CachedIntrospectionResults.clearClassLoader(getClassLoader());
}

📊 第三部分:关键源码类深度解析

3.1 DefaultListableBeanFactory:Spring的Bean工厂实现

类图关系

BeanFactory(接口)
    ↑
HierarchicalBeanFactory(接口)
    ↑
ConfigurableBeanFactory(接口)
    ↑
AutowireCapableBeanFactory(接口)
    ↑
AbstractBeanFactory(抽象类)
    ↑
AbstractAutowireCapableBeanFactory(抽象类)
    ↑
DefaultListableBeanFactory(具体实现)

核心数据结构

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
        implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
    
    // BeanDefinition存储:Map<beanName, BeanDefinition>
    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
    
    // BeanDefinition名称列表(保持注册顺序)
    private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
    
    // 单例Bean缓存
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
    private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
    
    // 已注册的BeanDefinition数量
    private volatile int beanDefinitionCount = 0;
}

设计模式应用

  1. 工厂模式:Bean创建的统一入口
  2. 模板方法模式AbstractBeanFactory定义骨架,子类实现具体步骤
  3. 注册表模式BeanDefinitionRegistry管理BeanDefinition

3.2 BeanDefinition:Bean的元数据描述

BeanDefinition接口层次

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
    
    // Bean作用域常量
    String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
    String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
    
    // 获取/设置Bean类名
    void setBeanClassName(String beanClassName);
    String getBeanClassName();
    
    // 设置/获取作用域
    void setScope(String scope);
    String getScope();
    
    // 懒加载设置
    void setLazyInit(boolean lazyInit);
    boolean isLazyInit();
    
    // 依赖设置
    void setDependsOn(String... dependsOn);
    String[] getDependsOn();
    
    // 是否是主候选Bean
    void setPrimary(boolean primary);
    boolean isPrimary();
    
    // 是否是自动装配候选
    void setAutowireCandidate(boolean autowireCandidate);
    boolean isAutowireCandidate();
    
    // 工厂Bean名称
    void setFactoryBeanName(String factoryBeanName);
    String getFactoryBeanName();
    
    // 工厂方法名称
    void setFactoryMethodName(String factoryMethodName);
    String getFactoryMethodName();
    
    // 构造器参数值
    ConstructorArgumentValues getConstructorArgumentValues();
    
    // 属性值
    MutablePropertyValues getPropertyValues();
    
    // Bean初始化方法
    void setInitMethodName(String initMethodName);
    String getInitMethodName();
    
    // Bean销毁方法
    void setDestroyMethodName(String destroyMethodName);
    String getDestroyMethodName();
    
    // Bean描述
    void setDescription(String description);
    String getDescription();
    
    // 获取Bean定义来源(配置文件、注解等)
    Resource getResource();
    
    // Bean定义是否来自外部(如XML配置)
    void setSource(Object source);
    Object getSource();
}

BeanDefinition实现类

实现类 用途 特点
GenericBeanDefinition 通用Bean定义 Spring 2.5+ 默认
RootBeanDefinition 根Bean定义 合并父定义,用于实际创建
ChildBeanDefinition 子Bean定义 继承父定义
AnnotatedGenericBeanDefinition 注解驱动的Bean定义 支持@Configuration@Bean
ScannedGenericBeanDefinition 组件扫描的Bean定义 支持@Component@Service

BeanDefinition合并过程

// AbstractBeanFactory.getMergedBeanDefinition()
protected RootBeanDefinition getMergedBeanDefinition(String beanName) throws BeansException {
    // 1. 检查缓存
    RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
    
    if (mbd != null) {
        return mbd;
    }
    
    // 2. 获取原始BeanDefinition
    BeanDefinition bd = getBeanDefinition(beanName);
    
    // 3. 如果有父定义,递归合并
    if (bd.getParentName() != null) {
        String parentName = bd.getParentName();
        RootBeanDefinition pbd = getMergedBeanDefinition(parentName);
        
        // 深度拷贝父定义
        mbd = new RootBeanDefinition(pbd);
        
        // 覆盖子定义属性
        mbd.overrideFrom(bd);
    }
    else {
        // 无父定义,直接转为RootBeanDefinition
        mbd = new RootBeanDefinition(bd);
    }
    
    // 4. 放入缓存
    this.mergedBeanDefinitions.put(beanName, mbd);
    
    return mbd;
}

性能优化:合并后的RootBeanDefinition被缓存,避免重复计算。


🛠️ 第四部分:设计模式在容器启动中的应用

4.1 模板方法模式(Template Method)

应用场景AbstractApplicationContext.refresh() 方法定义了13个步骤的固定顺序,但每个步骤的具体实现由子类决定。

源码示例

// AbstractApplicationContext
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // 1. 准备刷新
        prepareRefresh();
        
        // 2. 获取BeanFactory
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        
        // 3. 准备BeanFactory
        prepareBeanFactory(beanFactory);
        
        // ...
        
        // 13. 重置缓存
        resetCommonCaches();
    }
}

// 子类可以重写特定步骤
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 默认实现
}

设计优势

  1. 算法骨架固定:确保容器启动流程一致
  2. 步骤可定制:不同场景(Web、非Web)可以定制特定步骤

4.2 工厂模式(Factory)

应用场景BeanFactory 接口定义了Bean创建的工厂方法。

源码示例

public interface BeanFactory {
    
    // 核心工厂方法
    Object getBean(String name) throws BeansException;
    
    // 带类型参数的工厂方法
    <T> T getBean(String name, Class<T> requiredType) throws BeansException;
    
    // 带构造器参数的工厂方法
    Object getBean(String name, Object... args) throws BeansException;
    
    // ...
}

实现类DefaultListableBeanFactory 提供了具体实现。

4.3 观察者模式(Observer)

应用场景:Spring事件机制,ApplicationEventApplicationListener

源码示例

// 事件发布
public interface ApplicationEventPublisher {
    void publishEvent(ApplicationEvent event);
}

// 事件监听
public interface ApplicationListener<E extends ApplicationEventextends EventListener {
    void onApplicationEvent(E event);
}

工作流程

  1. 事件源发布 ApplicationEvent
  2. ApplicationEventMulticaster 广播事件
  3. 所有匹配的 ApplicationListener 接收并处理事件

4.4 策略模式(Strategy)

应用场景:资源加载策略,ResourceLoaderResource

源码示例

public interface ResourceLoader {
    Resource getResource(String location);
}

// 不同策略实现
// ClassPathResource:从类路径加载
// FileSystemResource:从文件系统加载
// UrlResource:从URL加载

设计优势:资源加载方式可替换,扩展性强。

4.5 建造者模式(Builder)

应用场景BeanDefinitionBuilder 用于构建复杂的BeanDefinition。

源码示例

public class BeanDefinitionBuilder {
    
    public static BeanDefinitionBuilder genericBeanDefinition() {
        return new BeanDefinitionBuilder(new GenericBeanDefinition());
    }
    
    public BeanDefinitionBuilder addPropertyValue(String name, Object value) {
        this.beanDefinition.getPropertyValues().add(name, value);
        return this;
    }
    
    public BeanDefinitionBuilder setFactoryMethod(String factoryMethod) {
        this.beanDefinition.setFactoryMethodName(factoryMethod);
        return this;
    }
    
    public AbstractBeanDefinition getBeanDefinition() {
        return this.beanDefinition;
    }
}

使用示例

BeanDefinition bd = BeanDefinitionBuilder
    .genericBeanDefinition(UserService.class)
    .addPropertyValue("username""admin")
    .addPropertyValue("password""123456")
    .setScope(BeanDefinition.SCOPE_SINGLETON)
    .getBeanDefinition();

⚡ 第五部分:性能优化与并发安全

5.1 启动性能优化

1. 减少Bean扫描范围

// 精确指定扫描包
@ComponentScan(basePackages = {"com.example.service", "com.example.dao"})

2. 使用懒加载

// 只有使用时才初始化
@Component
@Lazy
public class HeavyService {
    // 启动时不创建实例
}

3. 避免不必要的AOP代理

// final类无法被CGLIB代理
public final class UtilityClass {
    // 不需要代理的方法
}

5.2 运行时性能优化

1. 单例Bean缓存

// DefaultSingletonBeanRegistry.getSingleton()
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    // 一级缓存
    Object singletonObject = this.singletonObjects.get(beanName);
    
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        // 二级缓存
        singletonObject = this.earlySingletonObjects.get(beanName);
        
        if (singletonObject == null && allowEarlyReference) {
            // 三级缓存
            ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
            if (singletonFactory != null) {
                singletonObject = singletonFactory.getObject();
                this.earlySingletonObjects.put(beanName, singletonObject);
                this.singletonFactories.remove(beanName);
            }
        }
    }
    
    return singletonObject;
}

2. BeanDefinition缓存

// 合并后的BeanDefinition缓存
private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256);

5.3 并发安全设计

1. 同步控制

// AbstractApplicationContext.refresh()
public void refresh() throws BeansException, IllegalStateException {
    // 使用同步锁,防止并发刷新
    synchronized (this.startupShutdownMonitor) {
        // ...
    }
}

2. 线程安全集合

// 使用ConcurrentHashMap存储单例Bean
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

3. 双重检查锁定

// 创建单例Bean时的双重检查
protected Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    synchronized (this.singletonObjects) {
        Object singletonObject = this.singletonObjects.get(beanName);
        
        if (singletonObject == null) {
            // 创建前检查
            beforeSingletonCreation(beanName);
            
            try {
                // 创建实例
                singletonObject = singletonFactory.getObject();
            }
            catch (Throwable ex) {
                // 异常处理
                throw ex;
            }
            finally {
                afterSingletonCreation(beanName);
            }
            
            // 创建后放入缓存
            addSingleton(beanName, singletonObject);
        }
        
        return singletonObject;
    }
}

🔌 第六部分:扩展机制深度分析

6.1 BeanFactoryPostProcessor 扩展点

执行时机:在BeanDefinition加载后、Bean实例化前。

典型应用

  1. 修改BeanDefinition属性
@Component
public class VersionBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // 获取所有BeanDefinition名称
        String[] beanNames = beanFactory.getBeanDefinitionNames();
        
        for (String beanName : beanNames) {
            BeanDefinition bd = beanFactory.getBeanDefinition(beanName);
            
            // 为所有Service类添加版本属性
            if (bd.getBeanClassName() != null && 
                bd.getBeanClassName().contains("Service")) {
                bd.getPropertyValues().add("version""2.0.0");
            }
        }
    }
}
  1. 动态注册BeanDefinition
@Component
public class DynamicBeanRegistrar implements BeanDefinitionRegistryPostProcessor {
    
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
        // 动态创建BeanDefinition
        GenericBeanDefinition bd = new GenericBeanDefinition();
        bd.setBeanClassName("com.example.DynamicService");
        bd.setScope(BeanDefinition.SCOPE_SINGLETON);
        
        // 注册到容器
        registry.registerBeanDefinition("dynamicService", bd);
    }
    
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // 可以修改已注册的BeanDefinition
    }
}

6.2 BeanPostProcessor 扩展点

执行时机:在Bean实例化后、初始化前后。

典型应用

  1. 自定义注解处理
@Component
public class CustomAnnotationBeanPostProcessor implements BeanPostProcessor {
    
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        // 处理自定义注解
        Class<?> clazz = bean.getClass();
        
        if (clazz.isAnnotationPresent(CustomAnnotation.class)) {
            CustomAnnotation annotation = clazz.getAnnotation(CustomAnnotation.class);
            // 执行自定义逻辑
            System.out.println("Processing bean with custom annotation: " + beanName);
        }
        
        return bean;
    }
    
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        return bean;
    }
}
  1. AOP代理创建
// 简化版AOP代理创建逻辑
public Object createProxyIfNecessary(Object bean, String beanName) {
    // 检查是否需要代理
    if (!isProxyNeeded(bean)) {
        return bean;
    }
    
    // 创建代理
    ProxyFactory proxyFactory = new ProxyFactory();
    proxyFactory.setTarget(bean);
    proxyFactory.addAdvisor(new DefaultPointcutAdvisor(
        new AnnotationMatchingPointcut(null, CustomAnnotation.class),
        new CustomAdvice()
    ));
    
    return proxyFactory.getProxy();
}

6.3 ApplicationListener 事件监听

实战案例:应用启动后初始化缓存

@Component
public class CacheInitializer implements ApplicationListener<ContextRefreshedEvent> {
    
    @Autowired
    private CacheManager cacheManager;
    
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        // 确保是根上下文(避免Web应用中重复执行)
        if (event.getApplicationContext().getParent() == null) {
            // 初始化缓存
            initializeCaches();
            
            // 预热数据
            preloadHotData();
            
            System.out.println("Cache initialization completed.");
        }
    }
    
    private void initializeCaches() {
        // 创建缓存区域
        cacheManager.createCache("userCache", 
            new RedisCacheConfiguration().entryTtl(Duration.ofHours(1)));
        cacheManager.createCache("productCache",
            new RedisCacheConfiguration().entryTtl(Duration.ofMinutes(30)));
    }
    
    private void preloadHotData() {
        // 预热热点数据
        // ...
    }
}

🔍 第七部分:常见问题深度排查

7.1 Bean创建失败排查流程

1. 检查日志:Spring启动时会输出Bean创建日志
   ↓
2. 定位阶段:根据异常类型判断是哪个阶段出错
   - BeanDefinition解析异常 → 阶段二问题
   - BeanFactoryPostProcessor异常 → 阶段五问题
   - Bean实例化异常 → 阶段十一问题
   ↓
3. 调试源码:在对应阶段的关键方法打断点
   ↓
4. 分析原因:根据堆栈信息分析根本原因

7.2 循环依赖问题排查

现象BeanCurrentlyInCreationException

排查步骤

  1. 确认依赖关系
@Component
public class ServiceA {
    @Autowired
    private ServiceB serviceB;  // A依赖B
}

@Component  
public class ServiceB {
    @Autowired
    private ServiceA serviceA;  // B依赖A ← 循环依赖
}
  1. 检查注入方式

    • 构造器注入:Spring无法自动解决
    • Setter/字段注入:Spring可以解决(三级缓存)
  2. 解决方案

    • 使用@Lazy延迟注入
    • 重构代码,打破循环
    • 使用ApplicationContext.getBean()手动获取

7.3 Bean覆盖问题

场景:多个@Bean方法返回相同类型,或自动扫描与@Bean冲突。

排查

@Configuration
public class AppConfig {
    
    @Bean
    public UserService userService1() {  // 返回UserService类型
        return new UserService("v1");
    }
    
    @Bean  
    public UserService userService2() {  // 相同类型,后定义的会覆盖前者
        return new UserService("v2");    // 除非指定@Primary
    }
}

解决方案

  1. 使用@Primary指定主候选
  2. 使用@Qualifier指定具体Bean
  3. 修改Bean名称避免冲突

📈 第八部分:容器启动性能监控

8.1 启动时间监控

@Component
public class StartupMonitor implements ApplicationListener<ContextRefreshedEvent> {
    
    private static final Logger logger = LoggerFactory.getLogger(StartupMonitor.class);
    
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        // 计算启动时间
        long startupTime = System.currentTimeMillis() - event.getTimestamp();
        
        // 记录日志
        logger.info("Spring容器启动完成,耗时: {}ms", startupTime);
        
        // 输出Bean统计信息
        ConfigurableListableBeanFactory beanFactory = event.getApplicationContext().getBeanFactory();
        int beanCount = beanFactory.getBeanDefinitionCount();
        logger.info("容器中共有 {} 个Bean定义", beanCount);
    }
}

8.2 关键阶段耗时分析

@Aspect
@Component
public class RefreshPhaseMonitor {
    
    private Map<String, Long> phaseStartTimes = new ConcurrentHashMap<>();
    
    @Around("execution(* org.springframework.context.support.AbstractApplicationContext.refresh(..))")
    public Object monitorRefresh(ProceedingJoinPoint joinPoint) throws Throwable {
        long totalStart = System.currentTimeMillis();
        
        // 监控每个阶段
        phaseStartTimes.put("total", totalStart);
        
        Object result = joinPoint.proceed();
        
        long totalEnd = System.currentTimeMillis();
        logger.info("容器刷新总耗时: {}ms", totalEnd - totalStart);
        
        return result;
    }
    
    @Before("execution(* org.springframework.context.support.AbstractApplicationContext.prepareRefresh(..))")
    public void beforePrepareRefresh() {
        phaseStartTimes.put("prepareRefresh", System.currentTimeMillis());
    }
    
    @AfterReturning("execution(* org.springframework.context.support.AbstractApplicationContext.prepareRefresh(..))")
    public void afterPrepareRefresh() {
        long end = System.currentTimeMillis();
        long start = phaseStartTimes.get("prepareRefresh");
        logger.info("prepareRefresh阶段耗时: {}ms", end - start);
    }
    
    // ... 类似地监控其他关键方法
}

🎯 总结与行动指南

9.1 核心收获

维度 关键知识点
架构设计 三层架构(配置、定义、实例)、BeanFactory vs ApplicationContext
启动流程 refresh() 13个步骤、每个阶段的核心任务与扩展点
源码解析 DefaultListableBeanFactory、BeanDefinition层次结构
设计模式 模板方法、工厂、观察者、策略、建造者
性能优化 缓存机制、懒加载、并发安全设计
扩展机制 BeanFactoryPostProcessor、BeanPostProcessor、ApplicationListener

9.2 实战建议

1. 源码阅读路径

入口:AnnotationConfigApplicationContext构造器
    ↓
核心:AbstractApplicationContext.refresh()
    ↓
关键类:DefaultListableBeanFactory、AbstractAutowireCapableBeanFactory
    ↓
扩展点:BeanFactoryPostProcessor、BeanPostProcessor

2. 调试技巧

// 关键断点位置
1. AbstractApplicationContext.refresh() // 启动总入口
2. DefaultListableBeanFactory.preInstantiateSingletons() // Bean实例化入口
3. AbstractAutowireCapableBeanFactory.doCreateBean() // Bean创建核心逻辑
4. DefaultSingletonBeanRegistry.getSingleton() // 三级缓存处理

3. 性能优化检查清单

  • Bean扫描范围是否最小化
  • 非必要Bean是否标记为@Lazy
  • 单例Bean数量是否合理
  • 自定义扩展处理器是否影响启动性能
  • 缓存配置是否合适

 

Leave a Comment

Comments

No comments yet. Why don’t you start the discussion?

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注