Spring 循环依赖
来源:互联网 发布:初级程序员考试参考书 编辑:程序博客网 时间:2024/05/21 18:39
1、两个都是prototype的bean
两个bean都是prototype,只有在使用的时候才去创建bean。 AbstractBeanFactory类中doGetBean方法检测循环依赖。
// Fail if we're already creating this bean instance:// We're assumably within a circular reference.if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName);}
/** * Return whether the specified prototype bean is currently in creation * (within the current thread). * @param beanName the name of the bean */protected boolean isPrototypeCurrentlyInCreation(String beanName) { Object curVal = this.prototypesCurrentlyInCreation.get(); return (curVal != null && (curVal.equals(beanName) || (curVal instanceof Set && ((Set<?>) curVal).contains(beanName))));}
else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);}
protected void beforePrototypeCreation(String beanName) { Object curVal = this.prototypesCurrentlyInCreation.get(); if (curVal == null) { this.prototypesCurrentlyInCreation.set(beanName); } else if (curVal instanceof String) { Set<String> beanNameSet = new HashSet<String>(2); beanNameSet.add((String) curVal); beanNameSet.add(beanName); this.prototypesCurrentlyInCreation.set(beanNameSet); } else { Set<String> beanNameSet = (Set<String>) curVal; beanNameSet.add(beanName); }}
protected void afterPrototypeCreation(String beanName) { Object curVal = this.prototypesCurrentlyInCreation.get(); if (curVal instanceof String) { this.prototypesCurrentlyInCreation.remove(); } else if (curVal instanceof Set) { Set<String> beanNameSet = (Set<String>) curVal; beanNameSet.remove(beanName); if (beanNameSet.isEmpty()) { this.prototypesCurrentlyInCreation.remove(); } }}两个bean代码如下
@Component@Scope("prototype")public class BeanN1 { @Autowired private BeanN2 beanN2; @PostConstruct public void init() { System.out.println(beanN2); }}
@Component@Scope("prototype")public class BeanN2 { @Autowired private BeanN1 beanN1; @PostConstruct public void init() { System.out.println(beanN1); }}
启动之后获得bean
public static void main(String[] args) { //负责启动引导应用程序 ConfigurableApplicationContext run = SpringApplication.run(SpringBootDemoApplication.class, args); BeanN1 bean = run.getBean(BeanN1.class); System.out.println(bean);}
报如下错误:
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'beanN1': Requested bean is currently in creation: Is there an unresolvable circular reference?当获取BeanN1的时候,开始创建BeanN1,首先isPrototypeCurrentlyInCreation方法检测是否是循环依赖,prototypesCurrentlyInCreation里面是null,继续往下走,在创建BeanN1之前将beanN1放入prototypesCurrentlyInCreation中,此时prototypesCurrentlyInCreation是一个String类型,值是beanN1,因为beanN1依赖BeanN2,开始创建BeanN2,首先isPrototypeCurrentlyInCreation方法检测是否是循环依赖,prototypesCurrentlyInCreation里面是beanN1,继续往下走,在创建BeanN2之前将beanN2放入prototypesCurrentlyInCreation中,此时prototypesCurrentlyInCreation是一个Set类型,值是beanN1、beanN2,因为BeanN2依赖BeanN1,又需要创建BeanN1,当调用isPrototypeCurrentlyInCreation方法检测是否是循环依赖,prototypesCurrentlyInCreation里面是beanN1、beanN2,当前创建的是beanN1,所以检测出了循环依赖,直接抛出异常。
2.两个bean 一个Singleton一个prototype
@Component@Scope("prototype")public class BeanN1 { @Autowired private BeanN2 beanN2; @PostConstruct public void init() { System.out.println("BeanN1初始化:" + beanN2); }}
@Componentpublic class BeanN2 { @Autowired private BeanN1 beanN1; @PostConstruct public void init() { System.out.println("beanN2初始化:"); System.out.println(beanN1); System.out.println(this); }}
启动的时候看到输出如下:
BeanN1初始化:com.zhp.cyclic.dependency.BeanN2@602f8f94
beanN2初始化:
com.zhp.cyclic.dependency.BeanN1@42507640
com.zhp.cyclic.dependency.BeanN2@602f8f94
beanN2初始化:
com.zhp.cyclic.dependency.BeanN1@42507640
com.zhp.cyclic.dependency.BeanN2@602f8f94
因为beanN2是Singleton,启动的时候创建BeanN2对象,然后放入对象池中。
// Eagerly check singleton cache for manually registered singletons.Object sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null) { if (logger.isDebugEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.debug("Returning cached instance of singleton bean '" + beanName + "'"); } } bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);}然后解析BeanN2的依赖,它依赖BeanN1,BeanN1是prototype,开始创建BeanN1,BeanN1依赖BeanN2,直接从对象池中获取即可,BeanN1初始化完成。
// Guarantee initialization of beans that the current bean depends on.String[] dependsOn = mbd.getDependsOn();if (dependsOn != null) { for (String dep : dependsOn) { if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } registerDependentBean(dep, beanName); getBean(dep); }}BeanN1初始化完成之后,BeanN2也就可以正确的初始化了。
启动之后执行如下代码:
BeanN1 bean = run.getBean(BeanN1.class);System.out.println(bean);输出
BeanN1初始化:com.zhp.cyclic.dependency.BeanN2@602f8f94
com.zhp.cyclic.dependency.BeanN1@77083e41
com.zhp.cyclic.dependency.BeanN1@77083e41
我们看到BeanN2是单例,对象没变,BeanN1变了。和BeanN2中的BeanN1是不一样的。com.zhp.cyclic.dependency.BeanN1@42507640
3.两个对象都是Singleton
这种循环依赖是没问题的,完全可以创建成功。因为都是先创建对象,放入对象池,然后才组装依赖对象。
阅读全文
0 0
- spring循环依赖
- spring处理循环依赖
- JAVA,循环依赖,Spring
- spring循环依赖
- Spring 循环依赖
- spring 源代码 循环依赖
- spring循环依赖
- Spring 循环依赖
- Spring循环依赖
- spring 源码-循环依赖
- spring循环依赖问题
- spring循环依赖
- Spring处理循环依赖
- Spring循环依赖
- spring 循环依赖注入
- Spring中循环依赖
- Spring 循环依赖
- Spring中的循环依赖
- mui之ios上拉刷新不显示数据的bug
- 简单实现图片预加载(先下载模糊图,当高清图下载完成再替换成高清)
- cross origin requests are only supported for protocol schemes: http, data, chrome,
- 实验二双链表
- 分布式Tensorflow入门Demo
- Spring 循环依赖
- 用Kaptcha第三方包做验证码验证
- 农业物联网为食品安全保驾护航
- 传统旺季来临,中低压MOSFET缺货,台厂接单到手软
- python中list,str,json,dict使用
- NYOJ35 逆波兰表达式
- 软件测试基础-0基础必读神器
- 字符串算法——字符串匹配
- Spring学习教程-IOC