当前位置: 首页 > wzjs >正文

如何做品牌推广网站常用的搜索引擎有哪些?

如何做品牌推广网站,常用的搜索引擎有哪些?,做公司网站哪家好,毕设做网站Spring 通过 三级缓存机制 解决了 单例 Bean 的循环依赖问题,但无法处理 构造器注入的循环依赖。其核心思想是 提前暴露半成品 Bean 的引用,并通过 工厂对象(ObjectFactory) 动态生成代理对象,从而避免循环链条的无限递…

Spring 通过 三级缓存机制 解决了 单例 Bean 的循环依赖问题,但无法处理 构造器注入的循环依赖。其核心思想是 提前暴露半成品 Bean 的引用,并通过 工厂对象(ObjectFactory) 动态生成代理对象,从而避免循环链条的无限递归。


🧠 一、Spring 循环依赖的定义与限制

✅ 1. 循环依赖的定义

当两个或多个 Bean 相互依赖,形成一个闭环,称为 循环依赖(Circular Dependency)

示例:
@Component
class A {@Autowiredprivate B b;
}@Component
class B {@Autowiredprivate A a;
}

✅ 2. Spring 能解决的循环依赖类型

类型是否支持说明
字段/Setter 注入支持,使用三级缓存机制
构造器注入不支持,构造器注入需在实例化时完成依赖注入
多例(prototype)Bean不支持,Spring 无法管理多例 Bean 的生命周期

🔄 二、Spring 三级缓存机制详解

Spring 使用 三级缓存 来管理单例 Bean 的创建过程,确保在依赖注入时能获取到“早期引用”,从而打破循环依赖。

📦 1. 三级缓存的结构

Spring 使用 DefaultSingletonBeanRegistry 类中的三个 Map 实现三级缓存:

缓存层级类型作用
一级缓存(singletonObjects)Map<String, Object>存放完全初始化完成的 Bean(可直接使用)
二级缓存(earlySingletonObjects)Map<String, Object>存放提前暴露的“半成品 Bean”(已实例化,但未完成属性注入和初始化)
三级缓存(singletonFactories)Map<String, ObjectFactory<?>>存放生成 Bean 的工厂对象(用于生成代理对象)

🧱 三、Spring 创建 Bean 的流程与三级缓存的协作

Spring 创建单例 Bean 的核心流程如下:

1. 实例化 Bean(构造函数调用)
2. 将 Bean 工厂对象加入三级缓存(singletonFactories)
3. 填充属性(依赖注入)- 如果依赖的 Bean 尚未创建,则触发其创建流程
4. 初始化 Bean(调用 Aware、BeanPostProcessor、初始化方法)
5. 将 Bean 升级到一级缓存(singletonObjects)

✅ 1. 实例化 Bean

调用构造函数创建 Bean 实例,此时 Bean 是“半成品”,还未注入属性和初始化。

// AbstractAutowireCapableBeanFactory.java
protected Object createBeanInstance(...) {return getInstantiationStrategy().instantiate(...);
}

✅ 2. 将 Bean 工厂对象加入三级缓存

在实例化后,Spring 会将一个 ObjectFactory 放入三级缓存中,用于后续代理对象的生成。

// DefaultSingletonBeanRegistry.java
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {if (!this.singletonObjects.containsKey(beanName)) {this.singletonFactories.put(beanName, singletonFactory); // 放入三级缓存}
}

✅ 3. 填充属性(依赖注入)

在填充属性时,如果发现某个依赖的 Bean 还未创建,则会递归调用 getBean() 方法,尝试获取该 Bean。

// AbstractAutowireCapableBeanFactory.java
protected void populateBean(...) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {PropertyValues pvsToUse = ((InstantiationAwareBeanPostProcessor) bp).postProcessProperties(...);applyPropertyValues(beanName, mbd, bw, pvsToUse);}}
}
如果依赖的 Bean 还未完全初始化:
  • Spring 会调用 getSingleton(String beanName) 方法,尝试从缓存中获取 Bean。
  • 如果一级缓存没有,就尝试从二级缓存获取。
  • 如果二级缓存也没有,就从三级缓存中获取 ObjectFactory,调用 getObject() 生成 Bean 引用。
// DefaultSingletonBeanRegistry.java
public Object getSingleton(String beanName) {Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null) {ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);if (singletonFactory != null) {singletonObject = singletonFactory.getObject(); // 生成早期引用this.earlySingletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);}}}return singletonObject;
}

✅ 4. 初始化 Bean(调用 Aware、BeanPostProcessor、初始化方法)

初始化阶段包括:

  • 调用 BeanNameAwareBeanFactoryAware 等接口
  • 执行 BeanPostProcessor.postProcessBeforeInitialization()
  • 调用 @PostConstructInitializingBean.afterPropertiesSet()、自定义 init-method
  • 执行 BeanPostProcessor.postProcessAfterInitialization()
// AbstractAutowireCapableBeanFactory.java
protected Object initializeBean(...) {invokeAwareMethods(beanName, wrappedBean); // 调用 Aware 接口wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); // 前置处理器invokeInitMethods(beanName, wrappedBean, mbd); // 初始化方法wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); // 后置处理器return wrappedBean;
}

✅ 5. 将 Bean 升级到一级缓存

在 Bean 完全初始化完成后,将其从三级缓存中移除,放入一级缓存中,供后续使用。

// DefaultSingletonBeanRegistry.java
protected void addSingleton(String beanName, Object singletonObject) {this.singletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);this.earlySingletonObjects.remove(beanName);
}

🧩 四、AOP 代理的处理(结合三级缓存)

如果 Bean 需要 AOP 代理,Spring 会在 BeanPostProcessor.postProcessAfterInitialization() 中生成代理对象。

public Object postProcessAfterInitialization(Object bean, String beanName) {if (bean != null && !containsSingletonCandidate(beanName)) {return wrapIfNecessary(bean, beanName, new NullSourceClass());}return bean;
}

生成代理的过程会调用 AbstractAutoProxyCreator.getProxy(),最终生成一个代理对象。

这个代理对象会被缓存到 三级缓存 中,供其他 Bean 依赖注入时使用。


❗ 五、Spring 解决循环依赖的前提条件

条件说明
单例 BeanSpring 只能解决单例作用域 Bean 的循环依赖
Setter/字段注入支持,因为依赖注入发生在属性填充阶段
构造器注入❌ 不支持,构造器注入需在实例化时完成依赖注入
非代理对象如果 Bean 需要 AOP 代理,代理对象必须通过 ObjectFactory 提前生成

✅ 六、总结

特性Spring 三级缓存机制
解决类型单例 Bean、Setter/字段注入的循环依赖
不支持类型构造器注入、多例 Bean
核心机制提前暴露 Bean 的早期引用(半成品 Bean)
三级缓存结构singletonObjects(一级)、earlySingletonObjects(二级)、singletonFactories(三级)
缓存协作流程三级 → 二级 → 一级
AOP 代理处理通过 ObjectFactory 动态生成代理对象
核心类DefaultSingletonBeanRegistryAbstractAutowireCapableBeanFactory

🧪 七、完整流程图(简化版)

createBean(A)└── 实例化 A(构造函数)└── addSingletonFactory(A, ObjectFactory)└── populateBean(A)└── 依赖注入 b → getBean(B)└── createBean(B)└── 实例化 B(构造函数)└── addSingletonFactory(B, ObjectFactory)└── populateBean(B)└── 依赖注入 a → getBean(A)└── getSingleton(A) → 从三级缓存获取 A 的早期引用└── initializeBean(B)└── postProcessAfterInitialization() → AOP 代理(如有)└── addSingleton(B, proxyB)└── initializeBean(A)└── postProcessAfterInitialization() → AOP 代理(如有)└── addSingleton(A, proxyA)

http://www.dtcms.com/wzjs/526956.html

相关文章:

  • 开一个素材设计网站怎么做的南京网络推广公司排名
  • 建设工程查询扣分网站企业网站设计制作
  • 江苏 网站 备案生意参谋指数在线转换
  • 深圳交易网站建设东莞做一个企业网站
  • 免费网站建设品牌好网络维护公司
  • 黄山网站建设电话seo按照搜索引擎的
  • 海纳网站建设58黄页网推广公司
  • php网站里放asp活动推广文案
  • 网站空间一年多少钱网络营销自学网站
  • web前端工程师职业规划seo整站优化
  • 网站推广合同做好的网站怎么优化
  • 网站设计方案案例分析宁波seo排名外包
  • 做直播的视频在线观看网站深圳优化网站
  • 做网站一般字号要做多少搜索引擎推广实训
  • 东莞做外贸网站的公司seo优化服务是什么
  • 上海大公司有哪些网站优化比较好的公司
  • 佛山做网站公司排名免费推广的渠道有哪些
  • wordpress登陆地址修改免费seo课程
  • 网站建设公司选哪家成人教育培训机构排名
  • 宝应网站建设厦门网站建设平台
  • 西安旅游攻略2天自由行攻略广西seo经理
  • 科技设计网站建设佛山优化网站关键词
  • app要有网站做基础高级seo
  • wordpress点击图片直接相册浏览器关键词首页优化
  • 南阳美容网站建设黑科技引流工具
  • wordpress数据库压力seo外包大型公司
  • 网站域名的作用是什么意思seo核心技术排名
  • 网站开发 实战网站推广优化怎么做最好
  • 网站备案什么鬼什么是信息流广告
  • 网站流量超标河南郑州最新消息今天