Skip to content

SmartInitializingSingletonInitializingBean 的相同点和区别

这两个接口经常会被混淆,因为它们都和 Spring Bean 的初始化时机有关,但用途和触发时机不一样。

  • InitializingBean:关注自己,属性注入完成就执行(仅针对当前 Bean)。
  • SmartInitializingSingleton 关注全局,等所有单例初始化完成再执行(一次性全局触发。)

一. 相同点

方面描述
都是 Spring Bean 生命周期回调接口由 Spring 容器在特定时机调用,不需要手动调用。
都在 Bean 创建完成后 执行都是 Spring Bean 初始化阶段的钩子方法,用于执行额外逻辑。
都是 非必需接口实现与否完全取决于业务需要。
都可以配合 @PostConstructinit-method 使用属于同类的初始化扩展机制。

二. 区别

特性InitializingBeanSmartInitializingSingleton
接口定义public interface InitializingBean { void afterPropertiesSet() throws Exception; }public interface SmartInitializingSingleton { void afterSingletonsInstantiated(); }
调用时机当前 Bean 的所有属性填充完成(依赖注入完成)后立即调用容器中所有单例 Bean 都初始化完成后调用(延迟到整个上下文准备就绪)
粒度作用于单个 Bean,一个 Bean 实现就只会在它自己初始化完成时调用一次作用于全局单例 Bean 阶段,一个实现类的 Bean 会等所有单例都完成初始化后才调用一次
适用场景用于 单个 Bean 的属性检查/初始化,例如验证配置、开启资源连接等用于 依赖其他 Bean 完全初始化后的统一处理,例如批量注册、全局初始化依赖其他 Bean 的逻辑
是否依赖容器其他 Bean 完全就绪否,只要求自身依赖就绪即可是,必须等整个容器的单例初始化阶段结束
常见用法- 校验配置参数
- 初始化数据库连接/缓存等
- 事件发布器初始化(需依赖所有 Listener)
- 全局数据装载
- 注册与其他 Bean 交互的服务

三. 生命周期位置对比(简化版)

Spring Bean 初始化流程(单例)

实例化 Bean

依赖注入

调用 InitializingBean.afterPropertiesSet()

@PostConstruct / init-method

(对其他 Bean 重复以上流程,直到所有单例 Bean 都完成初始化)

调用 SmartInitializingSingleton.afterSingletonsInstantiated()

容器可用

四.举个代码例子

java
@Component
public class MyBean implements InitializingBean {
    @Override
    public void afterPropertiesSet() {
        System.out.println("MyBean 初始化完成(属性已注入)");
    }
}

@Component
public class MySmartBean implements SmartInitializingSingleton {
    @Override
    public void afterSingletonsInstantiated() {
        System.out.println("所有单例 Bean 都已初始化完成,MySmartBean 开始执行");
    }
}

运行输出:

text
MyBean 初始化完成(属性已注入)
所有单例 Bean 都已初始化完成,MySmartBean 开始执行

版权声明