Spring必问-bean生命周期和循环依赖
chatgpt回答
Spring Bean 的生命周期可分为以下阶段:
- 实例化:Spring容器根据配置文件或者注解等方式创建一个 Bean 实例,它是一个普通的 Java 对象。
- 属性赋值:Spring 容器通过 setter 方法或者构造器为 Bean 实例的属性赋值。
- BeanPostProcessor 前置处理:Spring 容器调用实现了 BeanPostProcessor 接口的类的 postProcessBeforeInitialization 方法,该方法在 Bean 实例化之后、初始化之前被调用,用于对 Bean 实例进行加工处理。
- 初始化:Spring 容器调用 Bean 实例的初始化方法,可以在 Bean 上使用 @PostConstruct 注解或者实现 InitializingBean 接口来指定初始化方法。
- BeanPostProcessor 后置处理:Spring 容器调用实现了 BeanPostProcessor 接口的类的 postProcessAfterInitialization 方法,该方法在 Bean 实例化之后、初始化之后被调用,用于对 Bean 实例进行加工处理。
- 使用:Spring 容器将 Bean 实例注入到其他 Bean 中或者在 BeanFactory 中管理,应用程序可以通过 ApplicationContext 获取 Bean 实例。
- 销毁:Spring 容器调用 Bean 实例的销毁方法,可以在 Bean 上使用 @PreDestroy 注解或者实现 DisposableBean 接口来指定销毁方法。
Spring 通过三级缓存解决循环依赖问题。当创建 Bean 实例时,Spring 会检查当前创建的 Bean 是否有依赖其他 Bean,如果有依赖,则会尝试从缓存中获取依赖的 Bean,如果缓存中没有,则会创建依赖的 Bean。
如果依赖的 Bean 也依赖当前 Bean,就会产生循环依赖。为了解决这个问题,Spring 采用了三级缓存:
- singletonObjects:缓存已经创建好的单例 Bean 实例。
- earlySingletonObjects:缓存正在创建中的 Bean 实例,还未进行属性注入。
- singletonFactories:缓存 Bean 工厂对象,用于解决循环依赖。
当 Spring 创建 Bean 实例时,会先将正在创建的 Bean 实例放入 earlySingletonObjects 缓存中,然后再创建依赖的 Bean 实例,如果依赖的 Bean 也依赖当前 Bean,就会从 singletonFactories 缓存中获取 Bean 工厂对象,通过工厂方法创建一个代理对象,再进行属性注入和初始化。
最后,再将创建好的 Bean 实例放入 singletonObjects 缓存中,并从 earlySingletonObjects 缓存中移除。这样就能够解决循环依赖问题。
#你觉得今年春招回暖了吗#