摸鱼学 Spring:Bean 的生命周期,面试官为啥总揪着问?

一、引言:摸鱼时的灵魂拷问

"嘿,摸鱼刷手机,突然想到面试官上次问 Spring Bean 的生命周期,当时支支吾吾没答好。现在得补补,不然下次面试又栽跟头。咱用大白话聊聊,就当摸鱼学习了。"

二、Bean 生命周期:从出生到死亡的 "剧本"

1. 实例化(new 对象)

  • 大白话 :Spring 先给 Bean "生" 出来,调用构造方法,就像new UserService(),这是第一步。

  • 代码举例

    csharp 复制代码
    public class UserService {
        public UserService() {
            System.out.println("UserService实例化(构造方法)");
        }
    }

2. 属性注入(填属性)

  • 大白话 :给刚生的 Bean "穿衣服",把依赖的其他 Bean 或配置值塞进去。比如@Autowired注入 DAO,或者 XML 里的<property>

  • 代码举例

    kotlin 复制代码
    public class UserService {
        @Autowired
        private UserDAO userDAO; // 注入属性
    }

3. 初始化前(BeanPostProcessor 预处理)

  • 大白话:Spring 的 "前置处理器" 先检查 Bean,搞点 AOP 代理啥的(比如事务增强)。这时候 Bean 还没完全初始化,先 "整整容"。

  • 代码举例(BeanPostProcessor)

    typescript 复制代码
    public class MyBeanPostProcessor implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) {
            System.out.println("初始化前处理:" + beanName);
            return bean;
        }
    }

4. 初始化(自己的初始化逻辑)

  • 大白话 :Bean 自己的 "初始化仪式",比如实现InitializingBean接口(afterPropertiesSet方法),或者配置init-method。这时候 Bean 终于 "ready" 了。

  • 代码举例(InitializingBean)

    csharp 复制代码
    public class UserService implements InitializingBean {
        @Override
        public void afterPropertiesSet() {
            System.out.println("UserService初始化(afterPropertiesSet)");
        }
    }
    // 或者XML配置init-method:<bean init-method="init"/>
    public void init() {
        System.out.println("自定义初始化方法");
    }

5. 初始化后(BeanPostProcessor 后处理)

  • 大白话:"后置处理器" 再检查一遍,比如生成最终的代理对象(AOP 的最后一步)。这时候 Bean 完全 "打扮好",可以用了。

  • 代码举例(BeanPostProcessor)

    typescript 复制代码
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        System.out.println("初始化后处理:" + beanName);
        return bean; // 比如返回代理后的Bean
    }

6. 使用(被调用)

  • 大白话:Bean 开始 "干活",比如处理 HTTP 请求、执行业务逻辑,这是它的 "职业生涯"。

7. 销毁(容器关闭时清理)

  • 大白话 :Spring 容器关闭时,Bean "退休",执行销毁逻辑。比如实现DisposableBeandestroy方法),或配置destroy-method,释放资源(比如数据库连接)。

  • 代码举例(DisposableBean)

    csharp 复制代码
    public class UserService implements DisposableBean {
        @Override
        public void destroy() {
            System.out.println("UserService销毁(destroy)");
        }
    }
    // 或者XML配置destroy-method:<bean destroy-method="destroy"/>
    public void destroy() {
        System.out.println("自定义销毁方法");
    }

三、核心代码串起来(XML 配置示例,简单明了)

ini 复制代码
<beans>
    <bean id="userService" class="com.example.UserService" 
          init-method="init" destroy-method="destroy">
        <property name="userDAO" ref="userDAO"/>
    </bean>
    <bean class="com.example.MyBeanPostProcessor"/>
</beans>
  • 执行顺序:构造→注入→初始化前→init 方法→初始化后→使用→destroy 方法(容器关闭时)。

四、实际场景:这玩意儿有啥用?

  1. AOP 实现:BeanPostProcessor 在初始化前后生成代理(比如事务切面),这就是 Spring AOP 的底层逻辑。
  2. 资源初始化 / 销毁:比如数据库连接池在初始化时创建连接,销毁时关闭(用 init-method 和 destroy-method)。
  3. 参数校验:初始化前检查 Bean 的属性是否合法(比如 @Validated 注解的处理,类似 BeanPostProcessor 的逻辑)。
  4. 框架扩展 :比如 MyBatis 的SqlSessionFactoryBean,在初始化时解析 XML,创建 SqlSessionFactory(用 afterPropertiesSet 方法)。

五、面试官为啥总问?

  1. 考察 Spring 核心理解:Bean 生命周期是 Spring 容器的核心机制,懂了它,才知道 Spring 如何管理对象,为啥能实现依赖注入、AOP 这些功能。
  2. 排查问题能力:比如 Bean 初始化失败(比如 init-method 抛异常),懂生命周期才能快速定位(是注入错了?还是初始化逻辑有问题?)。
  3. 框架扩展能力:如果你要写自定义 Spring Starter(比如集成 Redis),需要在 Bean 生命周期的某个阶段注册组件(比如初始化后创建 Redis 连接),这时候必须懂生命周期。

六、摸鱼总结

"原来 Bean 的生命周期就是这么个流程!现在再被面试官问,能从实例化到销毁,一步步说清楚。下次写代码时,遇到 Bean 初始化的问题,也知道从哪个阶段排查。摸鱼学技术,真香!"

相关推荐
花间相见25 分钟前
【LangChain组件03】—— LangChain Agents 执行与状态:工作流程与状态管理实战
java·前端·langchain
敲代码的嘎仔28 分钟前
28届后端开发-海康威视日常实习一面(已OC)
java·开发语言·后端·面试·海康威视·实习·大厂
kyriewen41 分钟前
面试官让我用 AI 重构一个 8 年陈的 React 组件——他说他不看代码,只看我会不会拆
前端·javascript·面试
IT_陈寒1 小时前
JavaScript数组排序踩的坑,差点让我加班到凌晨
前端·人工智能·后端
接着奏乐接着舞。1 小时前
【2026】73道Redis 常见面试题与参考答案
数据库·redis·后端·缓存
掘金者阿豪2 小时前
Seedance 2.0/2.5 虚拟素材能跨 Key 共用吗?一次讲清 Asset ID、账号隔离与 SaaS 素材架构
前端·后端
黄敬峰2 小时前
一文搞懂 Agent Memory 管理:从临时记忆到长期记忆
面试
程序员黎剑2 小时前
Spring-Bean生命周期-构造器访问Autowired字段为null
java·后端·spring
泡海椒2 小时前
JQuick-Curl 拦截器实战:统一 Token、日志、请求预处理,让第三方接口调用真正工程化
后端
古法安卓2 小时前
Android-重启流程源码解析
android·java·android studio