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

网站建设需要哪些软件百度软件下载安装

网站建设需要哪些软件,百度软件下载安装,海口代办注册公司哪家好,做网站怎么建立文件夹无代理对象的循环依赖 什么是循环依赖解决方案实现方式测试验证 引入代理对象的影响创建代理对象问题分析 源码见:mini-spring 什么是循环依赖 循环依赖是指在对象创建过程中,两个或多个对象相互依赖,导致创建过程陷入死循环。以下通过一个简…

无代理对象的循环依赖

    • 什么是循环依赖
    • 解决方案
      • 实现方式
      • 测试验证
    • 引入代理对象的影响
      • 创建代理对象
      • 问题分析

源码见:mini-spring

在这里插入图片描述

什么是循环依赖

循环依赖是指在对象创建过程中,两个或多个对象相互依赖,导致创建过程陷入死循环。以下通过一个简单的例子来说明:

public class A {  @Autowired  private B b;  public void func() {}  public B getB() {  return b;  }  public void setB(B b) {  this.b = b;  }  
}
public class B {  @Autowired  private A a;  public A getA() {  return a;  }  public void setA(A a) {  this.a = a;  }  
}

在上述代码中,类 A 依赖于 B(通过属性 b),而类 B 又依赖于 A(通过属性 a)。如果不加以处理,在创建 A 时会尝试注入 B,创建 B 时又需要注入 A,从而形成死循环,导致程序无法正常运行。


解决方案

对于没有代理对象的循环依赖问题,Spring 提供了一种简单有效的解决方案:提前暴露 Bean。核心思想是在 Bean 实例化完成后(但尚未完成属性注入),将其加入缓存,从而避免在属性注入阶段因循环依赖而导致的死循环。

实现方式

在 Spring 的 DefaultSingletonBeanRegistry 类中,引入二级缓存 earlySingletonObjects,用于存储提前暴露的 Bean 实例。虽然从实现角度看,将其放入一级缓存也可以解决问题,但 Spring 使用二级缓存是为了与已完全初始化的 Bean(存储在一级缓存中)进行区分。

// 二级缓存,保存实例化后的 Bean  
protected Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>();

接下来,修改单例 Bean 的获取逻辑。在 getSingletonBean 方法中,首先从一级缓存 singletonObjects 中查找 Bean,若未找到,则尝试从二级缓存 earlySingletonObjects 中获取:

@Override  
public Object getSingletonBean(String beanName) {  Object singletonObject = singletonObjects.get(beanName);  if (singletonObject == null) {  singletonObject = earlySingletonObjects.get(beanName);  }  return singletonObject;  
}

通过上述修改,一个基本的循环依赖解决方案即告完成。

测试验证

以下是测试代码,用于验证循环依赖是否被成功解决:

@Test  
public void testCircularReference() {  ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:circular-reference-without-proxy-bean.xml");  A a = applicationContext.getBean("a", A.class);  B b = applicationContext.getBean("b", B.class);  Assert.assertEquals(a.getB(), b);  
}

在创建 A 对象时,Spring 会在实例化完成后将其加入二级缓存 earlySingletonObjects。随后在注入属性时,需要创建 B 对象,而 B 依赖于 A。此时,Spring 直接从二级缓存中获取 A 实例,完成 B 的创建,并将 B 注入到 A 中,从而成功打破循环依赖。


引入代理对象的影响

如果 Bean 被代理(例如通过 AOP 实现),上述解决方案可能会失效。下面通过一个示例分析问题所在。

创建代理对象

假设对 A 对象应用代理,添加一个前置通知(Before Advice):

@Component  
public class ABefpreAdvice implements MethodBeforeAdvice {  @Override  public void before(Method method, Object[] args, Object target) throws Throwable {  System.out.println("before");  }  
}

Spring 的 XML 配置如下,其中 A 被配置为通过 AOP 代理:

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:context="http://www.springframework.org/schema/context"  xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans.xsd  http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-4.0.xsd">  <bean id="b" class="org.qlspringframework.test.bean.B">  <property name="a" ref="a"/>  </bean>  <!-- A 被代理 -->  <bean id="a" class="org.qlspringframework.test.bean.A">  <property name="b" ref="b"/>  </bean>  <bean class="org.qlspringframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>  <bean id="pointcutAdvisor" class="org.qlspringframework.aop.aspectj.AspectJExpressionPointcutAdvisor">  <property name="expression" value="execution(* org.qlspringframework.test.bean.A.func(..))"/>  <property name="advice" ref="methodInterceptor"/>  </bean>  <bean id="methodInterceptor" class="org.qlspringframework.aop.framework.adapter.MethodBeforeAdviceInterceptor">  <property name="advice" ref="beforeAdvice"/>  </bean>  <bean id="beforeAdvice" class="org.qlspringframework.test.common.ABefpreAdvice"/>  
</beans>

问题分析

在引入代理对象后,测试结果会发生变化。B 中注入的 A 实例是原始对象(实例化后但未完成初始化的对象),而从 Spring 容器中最终获取的 A 是代理对象,二者不再是同一个对象。这是因为 Spring 的二级缓存机制保存的是未代理的 A 实例,而代理对象是在后续阶段生成的。

因此,Assert.assertEquals(a.getB(), b) 可能失败,因为 a 是代理对象,而 b 中持有的 a 是原始对象。

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

相关文章:

  • 荆门城乡建设局网站广告投放代理商加盟
  • 软装设计用什么软件志鸿优化设计答案
  • 麟游住房和城市建设局网站企业网络推广方案
  • 教育网站建设开发sem代运营推广公司
  • 岳阳公司网站制作博客网站登录入口
  • 视觉元素网站郑州seo教程
  • 如何做短信验证码网站厦门seo顾问
  • 网站自助制作南宁seo
  • 盘锦门户网站制作北京网站设计公司
  • 东莞企业推广网络营销东莞优化排名公司
  • 我对网站开发的项目反思seo网络推广教程
  • 有没有做面粉美食的网站竞价广告是怎么推广的
  • 做网站编辑的感受百度推广电话销售话术
  • 自己做代购网站八爪鱼磁力搜索引擎
  • 6度建筑人才网网页怎么优化
  • 广州做网站平台的企业yy直播
  • 手机英文网站大全杭州网站建设方案优化
  • 网站建设和编辑实训报告排名前50名免费的网站
  • 正邦设计集团怎么快速优化关键词
  • 携程网站用js怎么做网站收录查询代码
  • 保山公司做网站深圳网络推广推荐
  • 线上电脑培训班飓风seo刷排名软件
  • 重庆网站建设企业灰色关键词怎么做排名
  • 苏州培训网站建设谷歌google下载
  • wordpress 虚拟商品插件优化大师优化项目有哪些
  • 阜宁网站制作收费在线咨询如何在网上做销售推广
  • python手机编程软件seo是如何优化
  • 网站的目标百度搜索排行榜风云榜
  • 企业取名字廊坊seo网站管理
  • 耐思尼克的建站宝盒灰色行业关键词优化