Skip to Content
面试题库Spring Core[面试题] 说一下Spring Bean的生命周期是怎么样的?

[面试题] 说一下Spring Bean的生命周期是怎么样的?

📖 版块 A:知识讲解版 (温故知新)

Spring Bean 的生命周期可以高度概括为四个阶段:实例化 (Instantiation) -> 属性赋值 (Populate) -> 初始化 (Initialization) -> 销毁 (Destruction)

  1. 实例化 (Instantiation)

    • Spring 通过反射机制,根据 BeanDefinition 创建 Bean 实例(此时仅仅是在堆内存中开辟了空间,属性还是默认值)。
  2. 属性赋值 (Populate)

    • Spring 容器根据配置(@Autowired、@Value等)进行依赖注入,填充 Bean 的各项属性。
  3. 初始化 (Initialization)

    • Aware 接口回调:如果 Bean 实现了 BeanNameAware、BeanFactoryAware 等接口,Spring 会将对应的 ID 或工厂实例注入进去。
    • BeanPostProcessor 前置处理:执行 postProcessBeforeInitialization 方法。
    • 初始化方法:执行 @PostConstruct 注解的方法、实现 InitializingBean 接口的 afterPropertiesSet 方法,以及配置的 init-method
    • BeanPostProcessor 后置处理:执行 postProcessAfterInitialization 方法。注意:AOP 的代理对象通常是在这一步生成的。
  4. 销毁 (Destruction)

    • 当容器关闭时,执行 @PreDestroy、实现 DisposableBean 接口的 destroy 方法,以及配置的 destroy-method

🎤 版块 B:面试实战版 (高手逐字稿)

Q:说一下 Spring Bean 的生命周期是怎么样的?

💬 高手逐字稿

关于 Spring Bean 的生命周期,我通常将其划分为四个核心阶段:实例化、属性填充、初始化、以及销毁。

首先是实例化阶段,Spring 容器会通过反射调用构造函数,在堆内存中把对象创建出来。这时候的 Bean 只是一个“半成品”,属性还没赋值。

接着是属性填充阶段,Spring 会扫描所有的注解或者 XML 配置,把这个 Bean 依赖的其他对象(比如用 @Autowired 标注的)或者基础配置值(@Value)注入进去。这一步也是解决循环依赖的关键时机。

然后进入最关键的初始化阶段。这里有很多扩展点,流程是:先执行各种 Aware 接口来让 Bean 感知到容器环境(比如拿到 BeanName 或者 BeanFactory);接着是 BeanPostProcessor 的前置处理;再之后会执行我们自定义的初始化逻辑,比如实现 InitializingBean 接口或者加了 @PostConstruct 注解的方法。

这里有一个非常重要的细节:在初始化阶段的最后一步,也就是 BeanPostProcessor 的后置处理方法中,Spring 会判断这个 Bean 是否需要进行 AOP 增强。如果需要,Spring 会在这里创建并返回一个代理对象(Proxy),而不是原始对象。这也是 Spring 能够实现声明式事务和日志拦截的核心原理。

最后就是销毁阶段,当 Spring 容器关闭时,会触发销毁回调,用于释放资源,比如关闭数据库连接池。

自问自答(进阶细节): 这时候可能会产生一个疑问:如果发生了循环依赖,AOP 代理还是在初始化最后一步生成的吗?其实这里 Spring 做了一个特殊的处理。如果发生了循环依赖,Spring 会通过三级缓存中的 ObjectFactory,提前在属性填充阶段就触发 BeanPostProcessor 来生成代理对象,并把代理对象存入二级缓存。这样就保证了被注入的其他 Bean 拿到的直接就是代理后的对象,而不是原始对象。

所以总结来说,Spring Bean 的生命周期设计得非常精妙,它通过大量的“钩子函数”和后置处理器,让我们可以不侵入源码地在各个阶段对 Bean 进行增强和定制。


最后更新于:
⏱️

登录后开始阅读

当前 MVP 版本只开放邮箱密码登录注册。完成登录后即可进入面试题内容。

还没有账号?先去注册