循环依赖

文章目录

循环依赖:若是在spring容器中存在三个service类,分别为ServiceAServiceBServiceC,并且ServiceA依赖ServiceBServiceB依赖ServiceCServiceC依赖ServiceA,这三者形成了一种循环依赖。

spring的循环依赖一般分为三种情况,构造器循环依赖,setter循环依赖,prototype循环依赖。


构造器循环依赖:在Spring创建ServiceA的时候,首先会将beanName->serviceA放入一个正在创建bean池,发现需要依赖ServiceB,会去创建ServiceB。在创建ServiceB的时候也会将beanName->serviceB放入正在创建bean池,发现需要依赖ServiceC,会去创建ServiceC。在创建ServiceC的时候也会将beanName->serviceC放入到正在创建bean池,发现需要依赖ServiceA,会去创建ServiceA。但是此时检查正在创建bean池时,发现ServiceA已经正在创建,就会抛出异常。

构造器循环依赖示例:

<?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"
xmlns:myname="http://www.test.com/schema/user"
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
http://www.test.com/schema/user
http://www.test.com/schema/user.xsd">

<bean id="serviceA" class="com.study.pack.xml.circle.ServiceA">
<constructor-arg index="0" ref="serviceB"></constructor-arg>
</bean>

<bean id="serviceB" class="com.study.pack.xml.circle.ServiceB">
<constructor-arg index="0" ref="serviceC"></constructor-arg>
</bean>

<bean id="serviceC" class="com.study.pack.xml.circle.ServiceC">
<constructor-arg index="0" ref="serviceA"></constructor-arg>
</bean>
</beans>
package com.study.pack.xml.circle;

import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

public class CircleTest {
public static void main(String[] args) {
XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("circle.xml"));
try {
ServiceA serviceA = (ServiceA)factory.getBean("serviceA");
} catch (Exception e) {
String message = e.getMessage();
System.out.println(message);
}
}
}

public class ServiceA {

private ServiceB serviceB;

public ServiceA(){}

public ServiceA(ServiceB serviceB) {
this.serviceB = serviceB;
}

public ServiceB getServiceB() {
return serviceB;
}

public void setServiceB(ServiceB serviceB) {
this.serviceB = serviceB;
}
}

package com.study.pack.xml.circle;

public class ServiceB {

private ServiceC serviceC;

public ServiceB() {}

public ServiceB(ServiceC serviceC) {
this.serviceC = serviceC;
}

public ServiceC getServiceC() {
return serviceC;
}

public void setServiceC(ServiceC serviceC) {
this.serviceC = serviceC;
}
}

package com.study.pack.xml.circle;

public class ServiceC {

private ServiceA serviceA;

public ServiceC() {}

public ServiceC(ServiceA serviceA) {
this.serviceA = serviceA;
}

public ServiceA getServiceA() {
return serviceA;
}

public void setServiceA(ServiceA serviceA) {
this.serviceA = serviceA;
}
}

setter循环依赖:

setter循环依赖示例:






prototype循环依赖:

prototype循环依赖示例: