Spring IoC 容器填充步骤总结

Spring IoC 容器填充步骤总结

Spring IoC(Inversion of Control)容器填充是 Spring 应用启动过程中的关键环节。以下是对容器填充步骤的详细解析,并结合丰富的源码示例、中文注释和更新后的 UML 流程图来说明每个步骤的作用及其在代码中的实现。

1. 准备上下文(Prepare the Context)

在 Spring 容器刷新前,Spring 会首先准备上下文环境。这包括设置启动时间、激活上下文标志和准备事件集合。

关键源码

// 准备刷新上下文
protected void prepareRefresh() {
    // 切换上下文为激活状态
    this.startupDate = System.currentTimeMillis();
    this.closed.set(false);
    this.active.set(true);

    // 初始化占位符属性源
    initPropertySources();

    // 验证所有必需属性是否已解析
    getEnvironment().validateRequiredProperties();

    // 允许收集早期的 ApplicationEvents
    this.earlyApplicationEvents = new LinkedHashSet<>();
}
2. 刷新 BeanFactory(Refresh the BeanFactory)

刷新 BeanFactory 是指销毁旧的 Bean 实例并加载新的 Bean 定义,确保上下文中的 BeanFactory 是最新的。

关键源码

// 获取并刷新 BeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    refreshBeanFactory();  // 刷新 BeanFactory
    return getBeanFactory();  // 返回 BeanFactory
}
3. 初始化 BeanFactory(Initialize the BeanFactory)

初始化 BeanFactory 过程中,设置类加载器、表达式解析器等必要的配置,并注册一些默认的环境 Bean。

关键源码

// 准备 BeanFactory
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 设置类加载器
    beanFactory.setBeanClassLoader(getClassLoader());
    // 设置表达式解析器
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    // 添加属性编辑器注册器
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

    // 注册默认环境 Bean
    if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
        beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
}
4. 后处理 BeanFactory(Post-Process the BeanFactory)

在 BeanFactory 标准初始化后,允许进一步自定义 BeanFactory 的设置。

关键源码

// BeanFactory 后处理
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 子类可覆盖此方法,进行定制化处理
}
5. 调用 BeanFactory 后处理器(Invoke BeanFactory Post-Processors)

Spring 会调用所有注册的 BeanFactoryPostProcessor,如 ConfigurationClassPostProcessor,负责解析 @Configuration 类并注册相应的 Bean 定义。

关键源码

// 调用 BeanFactory 后处理器
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
}
6. 注册 BeanPostProcessor(Register BeanPostProcessor)

Spring 注册 BeanPostProcessor,这些处理器会在每个 Bean 实例化前后进行拦截处理。

关键源码

// 注册 BeanPostProcessor
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
7. 初始化消息源(Initialize MessageSource)

消息源用于国际化支持,Spring 会在容器中查找或注册默认的 MessageSource 实例。

关键源码

// 初始化消息源
protected void initMessageSource() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
        this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
    } else {
        this.messageSource = new ResourceBundleMessageSource();
        beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
    }
}
8. 初始化事件广播器(Initialize Event Multicaster)

事件广播器负责在容器内分发事件。

关键源码

// 初始化事件广播器
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);
    }
}
9. 刷新应用上下文(Refresh the Application Context)

在特定的子类上下文中执行刷新操作,通常在 Web 应用中用于启动 Web 服务器。

关键源码

// 刷新上下文
protected void onRefresh() throws BeansException {
    // 子类可覆盖此方法,进行特定的刷新操作
}
10. 注册监听器(Register Listeners)

注册事件监听器,并将其绑定到事件广播器上,以便在容器运行期间接收事件。

关键源码

// 注册监听器
protected void registerListeners() {
    for (ApplicationListener<?> listener : getApplicationListeners()) {
        getApplicationEventMulticaster().addApplicationListener(listener);
    }
    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    for (String listenerBeanName : listenerBeanNames) {
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }
}
11. 实例化单例(Instantiate Singletons)

实例化所有的非懒加载的单例 Bean,并在上下文中注册。

关键源码

// 完成 BeanFactory 初始化
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(strVal -> 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();
}

总结

Spring IoC 容器填充是 Spring 应用启动过程中的一个复杂但至关重要的过程。通过丰富的源码示例、详细的中文注释和清晰的流程图,可以深入理解 Spring 容器的工作机制。每个步骤都展示了 Spring 框架的灵活性和扩展性,使得它能够满足各种应用场景的需求。

  • 14
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值