spring6-bean的生命周期与循环依赖

📅 发布时间:2026/7/4 21:11:36 👁️ 浏览次数:
spring6-bean的生命周期与循环依赖
bean的生命周期粗略划分5步实例化bean调用的是无参数的构造方法bean属性赋值执行set注入初始化bean调用bean的init方法需要自己写自己配使用bean销毁bean调用bean的destroy需要自己写自己配注意自定义的init和destroy需要在配置文件配置!-- init-method指定初始化方法destroy-method指定销毁方法-- !-- 这两个方法需要在bean类中定义-- bean iduser classcom.ali.bean.User init-methodinitBean destroy-methoddestroyBean/bean进一步七步在以上的5步中第三步是初始化bean。其实可以在初始化之前和初始化之后添加代码。此时需要加入“Bean后处理器”。编写一个类实现BeanPostProcessor类并重写before和after方法实例化bean调用的是无参数的构造方法bean属性赋值执行set注入执行“Bean后处理器”的before方法初始化bean调用bean的init方法需要自己写自己配执行“Bean后处理器”的after方法使用bean销毁bean// 日志类bean后处理器 public class LogBeanPostProcessor implements BeanPostProcessor { Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println(BeanPostProcessor befor方法); return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName); } Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println(BeanPostProcessor after方法); return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName); } }!-- 配置bean后处理器 这个bean后处理器会在bean实例化后和初始化前后执行相应的方法 例如可以在bean初始化前后打印日志 需要实现BeanPostProcessor接口 这样spring容器在创建其他bean时会自动调用这个后处理器的相应方法 例如上面的springBean在实例化和初始化时就会调用LogBeanPostProcessor中的方法 这样就可以在控制台看到日志输出 这个bean后处理器必须配置在spring配置文件中才能被spring容器识别和调用 这个bean后处理器将作用于当前配置文件中的所有bean -- bean classcom.ali.bean.LogBeanPostProcessor /精细化分为10步实例化bean调用的是无参数的构造方法bean属性赋值执行set注入检查bean是否实现Aware相关接口BeanNameAware, BeanClassLoaderAware, BeanFactoryAware如果实现了则调用这些接口相关的方法。执行“Bean后处理器”的before方法检查bean是否实现InitializingBean接口并调用接口方法初始化bean调用bean的init方法需要自己写自己配执行“Bean后处理器”的after方法使用bean检查bean是否实现了DisposableBean接口并调用接口方法销毁bean调用bean的destroy需要自己写自己配spring容器只对singleton的bean进行完整的生命周期管理。如果是prototype作用域的beanspring容器只负责初始化完毕等客户端程序一旦获取到该bean后spring容器就不再管理该对象的声明周期了。自己new的对象如何让spring容器管理使用DefaultListableBeanFactory类注入自己创建的对象。public static void main(String[] args) { User user new User(); System.out.println(user); // 将以上new的对象交给spring容器管理 DefaultListableBeanFactory beanFactory new DefaultListableBeanFactory(); beanFactory.registerSingleton(userBean, user); // 从spring容器中获取 Object userBean beanFactory.getBean(userBean); System.out.println(userBean); }bean的循环依赖问题bean的循环依赖A对象中有B属性。B对象中有A属性。这种你依赖我我依赖你的情况就是循环依赖。singletonsetter模式!-- singletonsetter方式解决循环依赖-- !-- 通过setter方法注入依赖可以解决循环依赖问题 -- !-- spring容器在创建bean时会先实例化bean对象然后通过setter方法注入依赖-- !-- 这样即使存在循环依赖spring也能正确创建和注入bean-- bean idhusbandBean classcom.ali.bean.Husband property namename valueJack/ property namewife refwifeBean/ /bean bean idwifeBean classcom.ali.bean.Wife property namename valueRose/ property namehusband refhusbandBean/ /bean在这种模式singletonsetter下主要分为2个阶段来解决 1. 在spring容器加载的时候实例化bean。只要其中任意一个bean实例化之后马上进行“曝光”【不等属性赋值就曝光】 2. bean“曝光”后再进行赋值prototypesetter模式!-- 在prototypesetter方式下无法解决循环依赖问题会出现异常 因为prototype作用域下spring容器不会缓存bean实例每次获取都会创建一个新的实例 这样当husbandBean实例化时wifeBean还没有被创建导致无法注入wifeBean 反之亦然最终会导致循环依赖失败抛出异常 所以prototype作用域下不支持循环依赖 但是当2个bean的scope不同时其中任意一个是singleton是可以的 例如下面的配置中husbandBean是singleton作用域wifeBean是prototype作用域 这样在创建husbandBean时wifeBean会被创建并注入 但是每次获取wifeBean时都会创建一个新的实例 这样就避免了循环依赖的问题 因为singleton只会创建一次而prototype每次获取都会创建新的实例 所以这种组合方式是可行的-- bean idhusbandBean classcom.ali.bean.Husband scopesingleton property namename valueJack/ property namewife refwifeBean/ /bean bean idwifeBean classcom.ali.bean.Wife scopeprototype property namename valueRose/ property namehusband refhusbandBean/ /bean