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

网站建设需要哪些软件上海网络营销推广外包

网站建设需要哪些软件,上海网络营销推广外包,h5网站开发公司,产品展示型网站模板无代理对象的循环依赖 什么是循环依赖解决方案实现方式测试验证 引入代理对象的影响创建代理对象问题分析 源码见: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/177434.html

相关文章:

  • 免费商会网站模板无锡百度正规公司
  • 网站运行费用北大青鸟软件开发培训学费多少
  • 站长之家收录查询资源网站优化排名优化
  • 为什么做的网站预览出来什么都没有网站查询seo
  • 怎样做免费网站的推广qq推广链接
  • 精仿手表网站谷歌优化方法
  • 做的很好的淘宝客网站完整企业网站模板
  • 郓城做网站aso优化是什么意思
  • 临沂网站开发技术员seo和sem的关系
  • 做网站被骗该咋样做vue seo 优化方案
  • 自己做盗版小说网站吗淘宝关键词怎么做排名靠前
  • 网站建设方案 filetype doc58精准推广点击器
  • 腾讯企业邮箱登陆入口seo搜索引擎优化工作内容
  • js网站评论框沧州seo包年优化软件排名
  • 如何做网站做网站需要多少钱今日头条最新消息
  • 贵阳网站建设有限公司模板网站建站公司
  • 广东微信网站制作公司网络推广方法有哪些
  • 杭州网站建设公司哪家好郑州品牌网站建设
  • 企业网站的制作方式公司网站页面设计
  • 西安公司网站制作价格竞价推广哪家公司好
  • 泰安聊城网站建设软文范文大全1000字
  • 网站域名注册多少钱系统清理优化工具
  • 体育课程网站建设有没有永久免费crm
  • 泉州教育网站搜索引擎营销的名词解释
  • 做网站要求什么做网站多少钱一年
  • 小说网站防盗做的最好的是seo关键词工具
  • 深圳做网站 信科便宜seo课程培训班费用
  • wordpress建站 图片百度seo快速排名
  • 海搜网做的网站怎么样做销售怎么和客户聊天
  • 广州建设网站的公司哪家好如何制作自己的网页