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

古典棕色学校网站模板最新舆情信息网

古典棕色学校网站模板,最新舆情信息网,一个公司名可以备案多少个网站,东莞现在属于什么风险地区Spring如何解决循环引用的问题 关于循环引用,首先说一个结论: Spring能够解决的情况为:两个对象都是单实例、且通过set方法进行注入。 两个对象都是单实例,通过构造方法进行注入,Spring不能进行循环引用问题&#x…

Spring如何解决循环引用的问题

关于循环引用,首先说一个结论:

Spring能够解决的情况为:两个对象都是单实例、且通过set方法进行注入

两个对象都是单实例,通过构造方法进行注入,Spring不能进行循环引用问题;

两个对象都是多实例的情况下,不管是set注入,还是构造注入,都不能解决Spring循环引用问题。

循环引用问题介绍

循环引用问题即:

有A,B两个类,A类中有B类型的成员变量b、B类中有A类型的成员变量a。创建a的过程需要b,创建b的过程又需要a;

循环引用问题演示

循环引用问题分析

请看如下流程:

  1. 调用getBean(“a”)来获取a对象;
  2. 先调用getSingleton(“a”)来尝试获取a,但是获取不到;
  3. 需要调用doCreateBean()来创建a;
  4. a的b属性是null,需要填充b属性;
  5. 调用getBean(“b”)来获取b对象;
  6. 先调用getSingleton(“b”)来尝试获取b,但是获取不到;
  7. 需要调用doCreateBean()来创建b;
  8. b的a属性是null,需要填充a属性;
  9. 又需要要调用getBean(“a”)来获取a。

这时getBean(“a”)可以获取到吗?如果能获取到,是在哪里获取的?如果获取不到,又会有什么问题呢?

我们首先看下getSingleton()源码:

image-20230809203549677

addSingleton方法如下图:

addSingleton

如此可以看到,在进行实例化、属性填充、初始化都完成后才会放到singletonObjects中。

那getSingleton()方法就获取不到a,只能再去创建a对象了吗?当然不是,如果再去创建a,a就不是单例的呢。

所以这就需要**没有创建完全的a也要存储起来。**但是并没有存储到singletonObjects中,因为singletonObjects是存储例化、属性填充、初始化都完成后的对象。

Spring又为我们定义了两个存储的位置:earlySingletonObjects、singletonFactories。

那什么时候将未创建完全的对象存储起来呢?

这我们应该在实例化对象完成后,填充属性前的代码查找。可以看到如下代码:

doCreateBean

addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));addSingletonFactory方法源码如下:
protected void addSingletonFactory(String beanName, ObjectFactory <? > singletonFactory) {Assert.notNull(singletonFactory, "Singleton factory must not be null");synchronized(this.singletonObjects) {if(!this.singletonObjects.containsKey(beanName)) {this.singletonFactories.put(beanName, singletonFactory);this.earlySingletonObjects.remove(beanName);this.registeredSingletons.add(beanName);}}
}

实例化后,会把创建非完全体对象的工厂放到singletonFactories里,这个工厂就是lambda表达式() -> getEarlyBeanReference(beanName, mbd, bean)调用的getEarlyBeanReference(beanName, mbd, bean)方法。

getEarlyBeanReference

addSingletonFactory还会把earlySingletonObjects、registeredSingletons中的对象删除。

singletonFactories
存储:不完全体的bean的id作为key,一个工厂作为value;
工厂方法是lambda表达式()->getEarlyBeanReference(beanName, mbd, bean)
此方法内部使用了BeanPostProcessor。

singletonFactories为什么不存储未完全体的a,而存储一个工厂方法呢?

这意味着他会处理一些复杂功能。

最简单的循环引用的问题

上述介绍的循环引用的问题,是最简单的情况。还有一些复杂情况。

如果A需要做AOP,需要为A做代理呢?或者B也要做代理呢?

复杂情况的循环引用

代理是在初始化阶段使用BeanPostProcessor的postProcessAfterInitialization()方法来做的。

singletonFactories存工厂的原因

singletonFactories存工厂的原因:

为b填充属性a时,需要获取到不完全体的a,为b赋值;
并且如果A需要做代理;
而代理是在BeanPostProcessor中的postProcessAfterInitialization()方法做的;
所以singletonFactories存储的是一个工厂(里面的方法是用BeanPostProcessor中的);
这样就无需在a初始化的过程中创建代理了,可以把a的代理提前创建出来。

那在A创建过程中是否还要创建代理呢?————不会。

在上面提前创建a的代理完成后,会将代理对象放到代理缓存中,在a初始化创建代理时,直接从代理缓存中拿就可以了。

站在b的角度讲,现在b的属性填充完成了,后面就是初始化了,在初始化过程中,就可以走正常的代理过程了。

a在填充属性时,就可以填充b的代理了,就可以走初始化了,初始化过程中的代理从代理缓存获取就可以了。

为b填充a代理对象分析

doGetBean()中的getSingleton方法:

getSingleton

getSingleton重载1

getSingleton重载2

在为b填充a的代理时,singletonFactory.getObject()就会回调存储起来的那个lambda表达式()->getEarlyBeanReference(beanName, mbd, bean)。

核心代码

会把a的代理获取出来;

然后把a的代理放到earlySingletonObjects中;

把存储的a工厂的lambda表达式从singletonFactories中移除。

b初始化完成后,b就是完全体了,调用addSingleton()方法就会把b存储到singletonObjects中了。

等a再初始化完成就是完全体了。

这样就解决了循环引用问题。

http://www.hkea.cn/news/574600/

相关文章:

  • 制作网页的网站有哪些网站建设
  • 日本真人做爰无遮挡视频免费网站嘉兴关键词优化报价
  • 忻州市中小企业局网站贵州整站优化seo平台
  • 网页怎么制作超链接seo兼职接单平台
  • 网站建设中应注意哪些问题重庆整站seo
  • 贵阳网站建设哪家便宜微商软文范例大全100
  • 怎么在微信上做网站竞价交易
  • wordpress优化版4.7.4网站seo设计
  • 网上课程网站精准客户数据采集软件
  • 专业网站建设报价外呼系统电销
  • 网站建设公司价格差别seo还有哪些方面的优化
  • 哪家公司建造了迪士尼乐园关键词优化推广排名多少钱
  • 做教育的网站有哪些内容吗湖南网站营销推广
  • wordpress 跳过ftp搜索引擎排名优化方案
  • 360做的网站北京营销推广公司
  • 我国政府网站建设的趋势宁波seo公司排名榜
  • 高端网站建设,恩愉科技专业的seo搜索引擎优化培训
  • 跨境网站开发公司网站seo思路
  • 冠县网站建设活动推广方案
  • 鲜花培训网站建设网站推广要点
  • 情趣内衣怎么做网站如何制作网页
  • 网站交互技术百度推广登陆后台
  • 网站的推广和宣传方式各行业关键词
  • 腾讯云服务器网站建设淘宝推广哪种方式最好
  • 大专网站建设论文找个免费的网站
  • 移动端网站开发流程图seopeix
  • 购物网站制作免费太原seo招聘
  • 怎么建设食品网站济南seo外包公司
  • 建设网站有哪些seopeix
  • 桂林市工程建设项目招标网站莆田百度快照优化