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

ftp上传网站后怎么弄网站如何备案icp

ftp上传网站后怎么弄,网站如何备案icp,静态网站开发项目实验报告,泉州英文网站建设有代理对象的循环依赖时,如何确保代理对象能够正确持有原始对象的所有属性赋值结果? 有代理对象的循环依赖时,如何确保代理对象能够正确持有原始对象的所有属性赋值结果?一、问题背景二、解答核心三、Spring 代理对象与属性赋值的…

有代理对象的循环依赖时,如何确保代理对象能够正确持有原始对象的所有属性赋值结果?

  • 有代理对象的循环依赖时,如何确保代理对象能够正确持有原始对象的所有属性赋值结果?
    • 一、问题背景
    • 二、解答核心
    • 三、Spring 代理对象与属性赋值的核心机制
      • 1. 代理对象的本质
      • 2. 属性赋值的对象
      • 3. 三级缓存的作用
      • 4. 关键点:代理对象如何“继承”属性
    • 四、详细流程分析
      • 1. 阶段一:创建 Bean A
      • 2. 阶段二:创建 Bean B
      • 3. 阶段三:完成 Bean A 的创建
      • 4. 阶段四:代理对象访问属性
    • 五、为什么代理对象能正确获取属性值?
      • 1. CGLIB 代理的实现
      • 2. JDK 动态代理的实现
      • 3. Spring 的缓存管理

源码见:mini-spring

在这里插入图片描述

有代理对象的循环依赖时,如何确保代理对象能够正确持有原始对象的所有属性赋值结果?

一、问题背景

在 Spring 解决有代理对象的循环依赖时,核心是通过三级缓存(singletonFactories)和 SmartInstantiationAwareBeanPostProcessorgetEarlyBeanReference 方法提前生成代理对象(如 AProxy)。但是,代理对象生成时,原始对象(如 A)可能尚未完成属性注入(例如 A 的属性 b 尚未赋值)。你的疑问是:

  • 提前生成的代理对象 AProxy 是基于“半成品”原始对象 A 创建的,此时 A 的属性(如 b)尚未赋值。
  • 在后续 A 的创建过程中,属性注入是针对原始对象 A 完成的。
  • 最终容器中的 AProxy 如何确保其属性(如 b)是正确赋值的?

二、解答核心

Spring 的代理对象(如通过 CGLIB 或 JDK 动态代理生成的 AProxy)通常是对原始对象 A 的包装,而不是一个独立的对象。代理对象通过持有原始对象的引用(称为 target),在调用时将请求委托给原始对象。因此,对原始对象 A 的属性赋值会直接反映到代理对象 AProxy,因为代理对象内部的逻辑依赖于原始对象的状态。

以下从机制和流程两个方面详细解答。


三、Spring 代理对象与属性赋值的核心机制

1. 代理对象的本质

  • JDK 动态代理:基于接口,代理对象实现与目标对象相同的接口,内部通过 InvocationHandler 持有原始对象的引用。
  • CGLIB 代理:基于子类,代理对象是原始对象的子类,继承了原始对象的字段,并通过 super 访问或直接持有原始对象的引用。
  • 在 Spring 的循环依赖场景中,代理对象(AProxy)通常通过 CGLIB 生成,代理对象会直接包含原始对象 A 的字段,或者通过某种方式(如委托模式)访问原始对象的字段。

2. 属性赋值的对象

  • 在 Spring 的 Bean 创建过程中,属性注入(如 @Autowired 或 Setter 注入)是直接针对原始对象 A 完成的
  • 代理对象 AProxy 本身并不直接参与属性注入,而是通过引用原始对象 A 来访问其属性值。

3. 三级缓存的作用

  • 三级缓存(singletonFactories)存储 ObjectFactory,通过 getEarlyBeanReference 提前生成代理对象 AProxy。
  • 二级缓存(earlySingletonObjects)保存提前暴露的代理对象 AProxy,供依赖方(如 B)使用。
  • 一级缓存(singletonObjects)最终存储完全初始化的代理对象 AProxy。

4. 关键点:代理对象如何“继承”属性

  • CGLIB 代理:AProxy 是 A 的子类,继承了 A 的所有字段。属性注入直接修改 A 的字段,而 AProxy 作为子类实例,天然持有这些字段值。
  • JDK 动态代理:AProxy 通过 InvocationHandler 持有原始对象 A 的引用,任何对字段的访问(如 getB())都会委托给原始对象 A,从而获取注入的属性值。
  • 因此,无论哪种代理方式,属性注入的结果都会反映在代理对象的行为中,因为代理对象最终依赖原始对象的状态。

四、详细流程分析

让我们以文章中的例子(A 依赖 B,B 依赖 A,且 A 被 AOP 代理)来梳理整个流程,重点说明属性赋值如何传递到代理对象。

1. 阶段一:创建 Bean A

  • 步骤
    • Spring 调用 A 的构造方法,生成原始对象 A(尚未进行属性注入)。
    • 将 A 封装为 ObjectFactory,加入三级缓存(singletonFactories),其中 ObjectFactory.getObject() 调用 getEarlyBeanReference。
    • A 需要注入属性 b(类型为 B),触发 B 的创建。
  • 状态
    • 此时,原始对象 A 的字段 b 为 null。
    • 三级缓存中存储了 A 的 ObjectFactory。

2. 阶段二:创建 Bean B

  • 步骤
    • Spring 创建 B 的原始对象,加入三级缓存。
    • B 需要注入 A(字段 a),Spring 调用 getSingleton(“A”):
      • 一级缓存(singletonObjects)和二级缓存(earlySingletonObjects)中没有 A。
      • 从三级缓存(singletonFactories)获取 A 的 ObjectFactory,调用 getObject()。
      • getEarlyBeanReference 被触发,SmartInstantiationAwareBeanPostProcessor(如 AbstractAdvisorAutoProxyCreator)生成 A 的代理对象 AProxy。
      • AProxy 加入二级缓存(earlySingletonObjects),从三级缓存移除。
    • B 的字段 a 被注入 AProxy,B 完成创建,放入一级缓存。
  • 状态
    • B 的字段 a 持有 AProxy。
    • 原始对象 A 的字段 b 仍为 null,因为 A 的属性注入尚未完成。
    • 二级缓存中存储了 AProxy。

3. 阶段三:完成 Bean A 的创建

  • 步骤
    • 返回到 A 的创建流程,Spring 对原始对象 A 进行属性注入:
      • 调用 Setter 方法(如 setB(B b))或直接通过反射设置字段 b。
      • 从一级缓存获取已创建的 B,注入到原始对象 A 的字段 b。
    • 原始对象 A 的字段 b 现在持有 B 的引用。
    • Spring 继续执行 A 的初始化,调用 BeanPostProcessor 的 postProcessAfterInitialization:
      • 检查 earlyProxyReferences,发现 A 已提前生成代理(AProxy),因此不重复生成。
    • Spring 从二级缓存获取 AProxy,将其放入一级缓存(singletonObjects)
  • 状态
    • 原始对象 A 的字段 b 已注入 B。
    • AProxy 作为 A 的子类(CGLIB)或通过 InvocationHandler 引用 A(JDK 代理),可以访问 A 的字段 b。
    • 一级缓存中的 AProxy 是最终暴露的对象,B 中的字段 a 也指向 AProxy。

4. 阶段四:代理对象访问属性

  • 访问机制
    • 当通过 AProxy 调用方法(如 getB())时:
      • CGLIB 代理:AProxy 继承了 A 的字段,getB() 直接返回 A 的字段 b(已注入 B)。
      • JDK 动态代理:AProxy 的 InvocationHandler 将 getB() 调用委托给原始对象 A,返回字段 b 的值。
    • 因此,AProxy.getB() 返回注入的 B,属性赋值结果成功反映在代理对象上。
  • 结果
    • 容器中的 A 是 AProxy,B 中的 a 也是 AProxy,引用一致。
    • AProxy 能够正确访问原始对象 A 的属性值(如 b),代理逻辑(如 AOP 切面)也能正常触发。

五、为什么代理对象能正确获取属性值?

1. CGLIB 代理的实现

  • 机制
    • CGLIB 生成的 AProxyA 的子类,继承了 A 的所有字段(如 private B b)。
    • 属性注入直接修改原始对象 A 的字段 b,而 AProxy 作为子类实例,共享这些字段值。
    • 调用 AProxy.getB() 时,直接访问继承的字段 b,返回注入的 B
  • 代码示例(简化):
    class A {private B b;public B getB() { return b; }public void setB(B b) { this.b = b; }
    }
    class AProxy extends A {// 继承了 A 的字段 b@Overridepublic B getB() {// AOP 拦截逻辑return super.getB(); // 访问父类 A 的字段 b}
    }
    
  • 结论
    • 属性注入修改了原始对象 A 的字段,而 AProxy 继承了这些字段,因此能直接访问注入的属性值。

2. JDK 动态代理的实现

  • 机制
    • JDK 动态代理生成 AProxy,实现与 A 相同的接口(如 IA),并通过 InvocationHandler 持有原始对象 A 的引用。
    • 属性注入修改原始对象 A 的字段 b
    • 调用 AProxy.getB() 时,InvocationHandler 将调用转发到原始对象 A,返回字段 b 的值。
  • 代码示例(简化):
    interface IA {B getB();
    }
    class A implements IA {private B b;public B getB() { return b; }public void setB(B b) { this.b = b; }
    }
    class AProxyHandler implements InvocationHandler {private A target;AProxyHandler(A target) { this.target = target; }public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// AOP 拦截逻辑return method.invoke(target, args); // 转发到原始对象 A}
    }
    
  • 结论
    • 属性注入修改了原始对象 A 的字段,AProxy 通过 InvocationHandler 访问 A 的字段,因此能获取注入的属性值。

3. Spring 的缓存管理

  • Spring 确保代理对象 AProxy 是最终暴露的对象(一级缓存和 B 的字段 a 都引用 AProxy)。
  • 属性注入发生在原始对象 A 上,但代理对象通过继承(CGLIB)或委托(JDK 代理)访问这些属性值,确保行为一致。

文章转载自:

http://zPCmghYG.trrhj.cn
http://AkYLte3L.trrhj.cn
http://Qe52SDxU.trrhj.cn
http://RUKz3NQV.trrhj.cn
http://LM636GW6.trrhj.cn
http://rKRNslyD.trrhj.cn
http://lFGHmNrL.trrhj.cn
http://9LBhhUqk.trrhj.cn
http://br73ftTd.trrhj.cn
http://OwbuCEwQ.trrhj.cn
http://OTYetcOQ.trrhj.cn
http://BIIxePqW.trrhj.cn
http://fNQPkWxw.trrhj.cn
http://eVsaMyi8.trrhj.cn
http://o7505vxo.trrhj.cn
http://eRen1d4r.trrhj.cn
http://3izBZVRt.trrhj.cn
http://n9hqvocL.trrhj.cn
http://i6ZyWVKJ.trrhj.cn
http://rL5yMHhP.trrhj.cn
http://MeSmzvES.trrhj.cn
http://Gu68SCYa.trrhj.cn
http://Lul2wgl5.trrhj.cn
http://1AEZrlCK.trrhj.cn
http://XVyyC4Mj.trrhj.cn
http://dP0W4lok.trrhj.cn
http://sJaEs1Z6.trrhj.cn
http://0ULygj6w.trrhj.cn
http://KI63J6Jl.trrhj.cn
http://TQE8uCMI.trrhj.cn
http://www.dtcms.com/wzjs/701696.html

相关文章:

  • 专业seo培训潍坊网站建设SEO优化熊掌号
  • 公司重名 做网站建设银行手机网站变
  • 龙岗免费的网站制作wordpress 图片路径
  • 新塘网站建设大学生免费服务器
  • 哈尔滨做网站巨耀公司中文网页开发工具
  • 网站怎么做pc端盒子赣州房产网
  • 企业做网站需要什么软件新网建立网站
  • 电子商务网站建设答案网站建设公司 广告法被处罚
  • 商务网站开发考卷网络广告一般收费价目表
  • 做的比较好的官方网站做免费嗳暧视频网站
  • 深圳市门户网站建设品牌百度竞价排名公式
  • 网站建站工具有哪些广州黄埔建网站
  • 安平县哪家做网站连云港 网站设计
  • 百度口碑苏州关键词优化企业
  • 腾讯云主机做网站上海平台网站建设公司
  • 域名和网站一样吗网站站点创建成功是什么意思
  • 合作网站制作微博营销的技巧有哪些
  • 婚介 东莞网站建设个体工商户 网站建设
  • 长沙网站优化步骤成都官网seo技术
  • 网站开发程序设计工程竣工验收公示网
  • 家庭宽带做私人网站找建站公司做网站注意事项
  • 郴州网站建设郴州贵阳seo网站推广优化
  • 成都网站建设方法数码京东seo搜索优化
  • 网站首页制作模板厦门网站建设制作工具
  • 蒙古文网站建设汇报材料爱心助学网站建设
  • 阜宁网站制作选哪家加强网站功能建设
  • 做微整去那个网站找好的医院软件开发人员工资标准
  • 狮岭做网站推广方案应该有哪些方面
  • 做网站分辨率多少钱2个网站 同意内容 百度优化
  • 自己建设网站不会咋办呀博爱seo排名优化培训