96SEO 2026-02-20 04:57 15
。

而循环依赖问题也是由Bean的生命周期过程导致的问题#…0、基础Bean的生命周期
在Spring中由于IOC的控制反转创建对象不再是简单的new出来而是交给Spring去创建会经历一系列Bean的生命周期才创建出相应的对象。
而循环依赖问题也是由Bean的生命周期过程导致的问题因此我们首先需要了解Bean的生命周期。
******************************************实例化123*******************************************
定位Spring容器会根据配置文件如XML、注解等或编程式配置来确定需要创建的Bean。
加载Spring容器会加载配置文件并解析其中的Bean定义将其转换为内部数据结构例如BeanDefinition。
实例化在实例化阶段Spring容器会根据Bean定义中的信息创建Bean的实例。
这个过程可以通过构造函数实例化、工厂方法实例化或者通过反射机制来实现。
*****************************************属性注入4*********************************************
属性注入在实例化Bean之后Spring容器会对Bean进行属性注入。
这可以通过setter方法注入、构造函数参数注入或字段注入等方式来完成。
****************************************初始化5~9********************************************
Aware接口回调如果Bean实现了Spring的Aware接口容器会通过回调方式将一些特殊的资源注入到Bean中。
例如如果Bean实现了BeanFactoryAware接口容器会将当前的BeanFactory实例注入到Bean中。
初始化前回调如果Bean实现了InitializingBean接口容器会在初始化之前调用它的afterPropertiesSet()方法给Bean一个机会执行一些初始化操作。
同时Spring容器还支持使用自定义的初始化方法。
初始化后回调如果Bean配置了初始化回调方法容器会调用该方法进行一些自定义的初始化逻辑处理。
后置处理器BeanPostProcessorSpring容器会调用注册的Bean后置处理器对Bean进行加工和增强。
例如可以通过AOP技术在这个阶段为Bean动态生成代理对象。
完成至此Bean已经成功创建并且已经完成了所有的初始化过程。
此时可以将Bean提供给其他对象使用。
****************************************销毁10、11******************************************
销毁前回调PreDestroy在容器关闭之前调用Bean的销毁前回调方法执行一些清理操作和释放资源的任务。
销毁容器关闭时销毁所有Bean实例包括调用相应Bean的销毁方法进行最终的清理和资源释放。
推断构造方法根据推断出来的构造方法反射得到一个对象我们称为原始对象填充原始对象中的属性依赖注入如果原始对象中的某个方法被
了那么则需要根据原始对象生成一个代理对象把最终生成的代理对象放入单例池源码中叫做
的生命周期也就会同样的需要A类的Bean就发生了循环依赖导致A和B的bean都创建不出来。
根据上文的分析我们发现出现循环依赖的根本原因是B的Bean需要注入A属性的时候Bean
需要时就可以从缓存中拿了这个缓存就应该是earlySingletonObjects放入缓存后再进行依赖注入。
由于提前暴露在创建B的Bean过程中当需要注入A的属性时就可以从缓存中拿到A提前暴露的原始对象还不是最终Bean就解决了问题。
关键在于全程只有一个A的原始对象其后续的生命周期没有变化。
因此对于不同时期的Bean如原始Bean、完整周期的Bean需要不同的缓存来存放底层源码中有三级缓存
HashMap(16);一级缓存singletonObjects缓存的是已经经历了完整生命周期的bean对象。
二级缓存earlySingletonObjects比
earlySingletonObjects三级缓存singletonFactories缓存的是
看似我们只需要1、2级缓存就能够解决问题了为什么需要三级缓存呢
上文的红字提到之所以能够提前暴露是因为假定的A的原始对象始终是同一个对象但如果有AOP的情况下呢我们考虑这样的场景
按照上文的分析假设创建B的bean过程中注入了A的原始对象属性。
然后A的原始对象采用AOP产生了一个代理对象即A的Bean变成了
实际上在有AOP的情况下Spring并没有像第2节所说直接将示例缓存到二级缓存而是生成完原始对象之后”多此一举“地将实例先封装到objectFactory中在需要引用的时候再通过singletonFactory.getObject()获取。
跟进getObject()方法其实执行了getEarlyBeanReference这个关键方法。
this.addSingletonFactory(beanName,
this.getEarlyBeanReference(beanName,
也就是说Spring将当前bean缓存到earlyProxyReferences中标识提前曝光的bean。
而wrapIfNecessary是用于Spring
AOP自动代理的也就是说在被提前引用前进行了AOP代理并得到了代理对象。
因此假设此时有其他对象依赖了A就可以从earlySingletonObjects中获取到A原始对象的代理对象了并且和A是同一个对象实现了目标。
注意postProcessAfterInitialization方法会当前beanName是否在earlyProxyReferences中如果在就AOP过了不在则执行AOP方法。
A对象而言已经完成创建了可以把它放入缓存singletonObjects中了因此从earlySingletonObjects
这里引用看到的一篇写的很清晰的博客http://t.csdn.cn/GeHkA的图来说明具体流程
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback