Spring循环依赖
来源:互联网 发布:mac guid分区方案 编辑:程序博客网 时间:2024/06/07 15:52
Spring循环依赖指的是类A依赖B,B又依赖A。这就依赖注入的时候会带来一定问题。下面说明一下,循环依赖的情况。
存在构造注入
public class AServieImpl implements AService{ private TestService testService; public void setTestService(TestService testService){ this.testService=testService; } public AServieImpl(){ }}
public class TestServiceImpl implements TestService { private AService aService; @Override public void test() { // TODO 自动生成的方法存根 System.out.println("test serviceimpl"); } public TestServiceImpl(AService aService){ this.aService=aService; }}
<bean class="com.test.service.impl.AServiceImpl" name="aService" id="aService" > <property name="testService" ref="testService"></property> </bean> <bean class="com.test.service.impl.TestServiceImpl" name="testService" id="testService" > <constructor-arg name="aService" ref="aService"></constructor-arg> </bean>
报错:
org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [com.test.service.impl.AServiceImpl] for bean with name ‘aService’ defined in ServletContext resource [/WEB-INF/spring.xml];
构造注入是先初始化依赖对象,在实例化本身的。所以,当TestServiceImpl要实例化时,先初始化AService,然后去找AService。然而设值注入是先实例本身,在初始化依赖对象的。所以AService先实例化本身,同时要求依赖TestServiceImpl,然后并没有找到TestServiceImpl。所以报错。
Spring容器将每一个正在创建的bean标识符放在一个”当前创建bean池”中,bean标识符在创建过程中将一直保持在这个池中,因此如果在创建bean过程中发现自己已经在”当前创建bean池”里时,将抛出BeanCurrentlyInCreationException异常表示循环依赖;而对于创建完毕的bean将从”当前创建bean池”中清除掉。对于setter注入造成的依赖是通过Spring容器提前暴露刚完成无参构造函数实例化但未完成其他步骤(如setter注入)的bean来完成的,而且只能解决单例作用域的bean循环依赖。通过提前暴露一个单例工厂方法,从而使其他bean能引用到该bean:
addSingletonFactory(beanName, new ObjectFactory() { public Object getObject() throws BeansException { return getEarlyBeanReference(beanName, mbd, bean); } });
单体的设值注入
public class AServieImpl implements AService{ private TestService testService; public void setTestService(TestService testService){ this.testService=testService; }}
public class TestServiceImpl implements TestService { private AService aService; @Override public void test() { // TODO 自动生成的方法存根 System.out.println("test serviceimpl"); } public void setaService(AService aService) { this.aService = aService; }}
<bean class="com.test.service.impl.AServieImpl" name="aService" id="aService" > <property name="testService" ref="testService"></property> </bean> <bean class="com.test.service.impl.TestServiceImpl" name="testService" id="testService" > <property name="aService" ref="aService"></property> </bean>
单体的set注入是可以的。
但对于非单体就不行了。因为Spring容器不进行缓存”prototype”作用域的bean,因此无法提前暴露一个创建中的bean。
- spring循环依赖
- spring处理循环依赖
- JAVA,循环依赖,Spring
- spring循环依赖
- Spring 循环依赖
- spring 源代码 循环依赖
- spring循环依赖
- Spring 循环依赖
- Spring循环依赖
- spring 源码-循环依赖
- spring循环依赖问题
- spring循环依赖
- Spring处理循环依赖
- Spring循环依赖
- spring 循环依赖注入
- Spring中循环依赖
- Spring 循环依赖
- Spring中的循环依赖
- webView网页加载
- springMvc请求路径小解
- 常见数列
- 第一篇写给自己
- js排序算法详解-插入排序
- Spring循环依赖
- 单例模式
- poj2773(互质)
- spring事务管理
- 统计专业人数
- java.util.Stack类中 empty() 和 isEmpty() 方法的作用
- js排序算法详解-希尔排序
- 算法分析基础
- Caused by: org.springframework.beans.factory.BeanExpressionException: Expression parsing failed;