Spring 循环依赖指的是 SpringBean 对象之间的依赖关系形成一个闭环。即在代码中,把两个或者多个 Bean 相互之间去持有对方的引用,就会发生循环依赖,循环依赖会导致注入出现死循环,这是 Spring 发生循环依赖的主要原因之一。
这两天工作遇到了一个挺有意思的Spring循环依赖的问题,但是这个和以往遇到的循环依赖问题都不太一样,隐藏的相当隐蔽,网络上也很少看到有其他人遇到类似的问题。这里权且称他非典型Spring循环依赖问题。但是我相信我肯定不是第一个踩这个坑的,也一定不是最后一个,可能只是因为踩过的人比较少、鲜有记录罢了。因此这里权且记录一下这个坑,方便后人查看。
最近项目组的一个同事遇到了一个问题,问我的意见,一下子引起的我的兴趣,因为这个问题我也是第一次遇到。平时自认为对spring循环依赖问题还是比较了解的,直到遇到这个和后面的几个问题后,重新刷新了我的认识。
# [Spring 的循环依赖问题](https://www.cnblogs.com/mghio/p/15024461.html)
本文是spring源码浅析系列的第一篇。全文总共分为四部分,第一部分总结一下 Spring的好处,毕竟如果不好用,它也不会迅速在开发框架里迅速脱颖而出。第二部分主要介绍一下Spring组织代码的底层软件开发逻辑,可以让你知其然更知其所以然。第三部分主要通过spring组成部分的接口与类的继承关系的对比,来说明spring中两驾马车BeanFactory和ApplicationContext间的区别和联系。第四部分,也是本文扣题部分,讲解spring应用最终成功创建依赖于bean及其运行容器,是经由什么样一个原理完成创建并发生关联的,这部分有些环节介绍的较为详细,有些部分一笔带过,原因是有些通过方法名称你基本知道它存在的作用,同时实现逻辑也并不复杂,所以就只做简略概括。文中使用版本是Spring Boot 2.1.2.RELEASE(即Spring 5.1.4),以默认配置启动,分析一下框架的工作原理。
多个bean之间相互依赖,形成了一个闭环。比如:A依赖于B、B依赖于C、C依赖于A。
人类对图形的接受和处理能力高于对文字和数字的处理能力。 如果我们学习某个知识的时候,能够找到配套的图,理解会好很多。 但,并不是所有的知识都有配图。
循环依赖其实就是循环引用,也就是两个或则两个以上的bean互相持有对方,最终形成闭环。比如A依赖于B,B依赖于C,C又依赖于A。如下图:
Spring可以做很多事情,它为企业级开发提供给了丰富的功能,但是这些功能的底层都依赖于它的两个核心特性,也就是控制反转(Inversion of Control,IOC)和面向切面编程(aspect-oriented programming,AOP)。
spring ioc 即控制反转,就是将我们创建和管理对象交给了spring进行处理; 我们只需要通过配置文件描述对象, 容器加载配置文件描述,并将其转换为Bean Difinition , 然后通过BeanFactory 来生产对象,当然单利在创建一次后会缓存在bean容器中。
因为要用到Spring的初始化加载bean,比如Spring上下文的获取类应该优先加载,监听什么的类应该在启动后加载,所以考虑先后顺序,所以研究一下ApplicationRunner、InitializingBean、@PostConstruct的执行先后顺序问题
1.说下Struts的设计模式 MVC模式: web应用程序启动时 就会加载并初始化ActionServler。 用户提交表单时, 一个配置好的ActionForm对象被创建, 并被填入表单相应的数据, ActionServler根据Struts-config.xml文件 配置好的设置决定是否需要表单验证, 如果需要就调用ActionForm的Validate() 验证后选择将请求发送到哪个Action, 如果Action不存在, ActionServlet会先创建这个对象, 然后调用Action的exe
作者个人研发的在高并发场景下,提供的简单、稳定、可扩展的延迟消息队列框架,具有精准的定时任务和延迟队列处理功能。自开源半年多以来,已成功为十几家中小型企业提供了精准定时调度方案,经受住了生产环境的考验。为使更多童鞋受益,现给出开源框架地址:
Spring源码解析之八finishBeanFactoryInitialization方法即初始化单例bean
依赖注入(IoC) 和 控制反转(DI) 有什么关系呢?其实它们是同一个概念的不同角度描述。
IoC容器的初始化就是含有BeanDefinition信息的Resource的定位、载入、解析、注册四个过程,最终我们配置的bean,以beanDefinition的数据结构存在于IoC容器即内存中。这里并不涉及bean的依赖注入,只是bean定义的载入。但有例外,在使用Ioc容器时有一个预实例化的配置,即bean定义中的设置了lazyinit属性,那么这个bean在Ioc容器初始化时就预先加载,不需要等到Ioc整个初始化后,第一次getBean时才会触发。其中refresh()启动对Ioc容器的初始化。
在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。理解好Ioc的关键是要明确“谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”,那我们来深入分析一下:
循环依赖即:bean A依赖于另一个bean B,而bean B又依赖于bean A,这个时候就很容易形成一个闭环甚至死循环下去。
在使用Spring时,Bean之间会有些依赖,比如一个Bean A实例化时需要用到Bean B,那么B应该在A之前实例化好。很多时候Spring智能地为我们做好了这些工作,但某些情况下可能不是,比如Springboot的@AutoConfigureAfter注解,手动的指定Bean的实例化顺序。了解Spring内Bean的解析,加载和实例化顺序机制有助于我们更好的使用Spring/Springboot,避免手动的去干预Bean的加载过程,搭建更优雅的框架。
A.IOC就是指程序之间的关系由程序代码直接操控。 B.所谓“控制反转”,是指控制权由应用代码转到外部容器,控制权的转移 C.IOC将控制创建的职责搬进了框架中;并把它从应用代码脱离开来 D.当使用Spring的IOC容器时只需指出组件需要的对象,在运行时Spring的IOC容器会根据XML配置数据提供给它。
IOC全称 Inversion Of Control ,意为控制反转,通过IOC容器,我们把对象或者组件的创建过程透明化;我们无需关注创建细节,我们只需要把创建对象,属性赋值,这些工作交给IOC容器完成即可。
面试指南系列,很多情况下不会去深挖细节,是小六六以被面试者的角色去回顾知识的一种方式,所以我默认大部分的东西,作为面试官的你,肯定是懂的。
实际的系统几乎不可能仅有单一的bean,都是很多个bean协作提供服务。本文目标也就是讨论如何冲破单一 bean 定义而让多 bean 协作实现系统。
各位小伙伴大家好,我是A哥。上篇文章了解了static关键字 + @Bean方法的使用,知晓了它能够提升Bean的优先级,在@Bean方法前标注static关键字,特定情况下可以避免一些烦人的“警告”日志的输出,排除隐患让工程变得更加安全。我们知道static关键字它不仅可使用在方法上,那么本文将继续挖掘static在Spring环境下的用处。
如上述代码所示,通过@Order注解定义优先级,3个Bean对象从IOC容器中的加载顺序为:Test01、Test02、Test03。
假设有这么一个需求,要求在项目启动过程中,完成线程池的初始化,加密证书加载等功能,你会怎么做?如果没想好答案,请接着往下看。今天介绍几种在Spring Boot中进行资源初始化的方式,帮助大家解决和回答这个问题。
对于这样的问题,大部分人都是处于一种朦朦胧胧的状态,说的出来,但又不是完全说的出来,今天我们就以架构设计的角度尝试解开Spring的神秘面纱。
ApplicationContent 是 Spring 中的核心容器,而refresh方法是对Application的初始化,我们下面来学习一下
在使用Spring的过程中比较好的设计是bean不依赖于容器。在一些特殊的情况下需要感知容器的存在,使用容器的提供的资源。Spring IoC容器提供了Aware机制。
SpringBoot中的IoC (原创内容,转载请注明来源,谢谢) 一、Spring IoC IoC又称为依赖反转,有两种方式,一种是DI(依赖注入),另一种是DL(依赖查找)。DI是当前实体被动依赖其他组件的IoC注入,DL是当前实体主动注册某个服务。 典型的Spring IoC方式如下: ApplicationContextcontext = new FileSystemXmlApplicationContext(....); MockServiceservice = context.getBean(
今天小伙伴跑过来说,搭建框架的时候出现disconf配置好的信息不能够及时注入到实体类中的情况。他通过实践发现,spring 加载Configuration 的时候,通过@Autowired注入的RedisProperties 实体类里面没有值。等到容器加载完成后,在Controller 层注入的RedisProperties是有数据的,搞了接近一天。我在他控制台看到了如下信息(简化):
Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性的角度而言,绝大部分Java应用都可以从Spring中受益。 Spring优点: 低侵入式设计,代码的污染极低; 独立于各种应用服务器,基于Spring框架的应用,可以真正实现Write Once,Run Anywhere的承诺; Spring的IoC容器降低了业务对象替换的复杂性,提高了组件之间的解耦 S
Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性的角度而言,绝大部分Java应用都可以从Spring中受益。 Spring优点: 低侵入式设计,代码的污染极低; 独立于各种应用服务器,基于Spring框架的应用,可以真正实现Write Once,Run Anywhere的承诺; Spring的IoC容器降低了业务对象替换的复杂性,提高了组件之间的解耦
大体来说,经历以下过程:接口需求调研、接口测试工具选择、接口测试用例编写、接口测试执行、接口测试回归、接口测试自动化持续集成。具体来说,接口测试流程分成以下九步:
在Spring项目经常遇到@PostConstruct注解,首先介绍一下它的用途: 被注解的方法,在对象加载完依赖注入后执行。
在 Spring 中,bean 往往不会独立存在,bean 的相互依赖是极为常见的。在这一过程中,错综复杂的 bean 依赖关系一旦造成了循环依赖,往往十分令人头疼,那么,作为使用者,如果遇到了循环依赖问题,我们应该如何去解决呢?本文我们就来为您详细解读。
Spring框架是一个开源的轻量级的DI和AOP容器框架,致力于简化企业级应用开发,让开发者使用简单的Java Bean来实现从前只有EJB才能实现的功能。
依赖注入就是在Spring创建Bean的时候,去实例化该Bean构造函数所需的参数,或者通过Setter方法去设置该Bean的属性。
截止到目前Spring 框架已集成了 20 多个模块 。 这些模块主要被分如下图所示的核心容器 、 数据访问 / 集成 、Web、AOP (面向切面编程) 、 工具 、 消息和测试模块 。
低级容器BeanFactory可以理解为就是个HashMap,Key是BeanName,Value是Bean实例,通常只提供注册(put),获取(get)这两个功能;是IOC容器的基础接口,所有的容器都是从它这里继承实现而来,BeanFactory作为SpringIOC容器,管理着Bean的生命周期,控制着Bean的依赖注入;
spring 单例对象的实例化、初始化过程是在doCreateBean中(之前仅仅是注册好了BeanDefenition), 大概分为三步:
尽管希腊哲学家赫拉克利特(Heraclitus)并不作为一名软件开发人员而闻名,但他似乎深谙此道。他的一句话经常被引用:“唯一不变的就是变化”,这句话抓住了软件开发的真谛。
5.Spring并不强制应用完全依赖于Spring,开发者可自由选用Spring框架的部分或全部
AOP (Aspect Orient Programming),直译过来就是 面向切面编程。AOP 是一种编程思想,是面向对象编程(OOP)的一种补充。面向对象编程将程序抽象成各个层次的对象,而面向切面编程是将程序抽象成各个切面。
领取专属 10元无门槛券
手把手带您无忧上云