spring依赖注入_Spring的依赖注入陷阱

spring依赖注入

Spring框架中有三种注入变量:

  • 基于二传手的注射
  • 基于构造函数的注入
  • 基于现场的注入

这些机制中的每一种都有优点和缺点,并且不仅只有一种正确的方法。 例如现场注入:

@Autowired
private FooBean fooBean;

在生产代码中使用它通常不是最好的主意,主要是因为它使我们的bean无法在不启动Spring上下文或不使用反射hack的情况下进行测试。 另一方面,它几乎不需要其他代码,并且可以在集成测试中使用-绝对不会独立实例化。 我认为这是基于现场注射的唯一情况。

现在,让我们集中讨论两个主要变体。 在Spring文档中,我们可以读到

…将构造函数参数用于强制性依赖项并将设置器用于可选的依赖项是一个很好的经验法则。

同样在参考Spring到3.1的文档中 ,我们可以找到一个句子

Spring团队通常提倡setter注入,因为大量的构造函数参数可能变得笨拙,尤其是当属性是可选的时。

这种情况在文档中已更改为第四版,其中指出:

Spring团队通常提倡构造函数注入,因为它使人们能够将应用程序组件实现为不可变对象,并确保所需的依赖项不为null。

尤其是在版本4.0之前的人们使用基于构造函数的注入方法(其中也有些“纯粹主义者”)(这也可以在本文档中找到)的时候, 这很酷:)请注意,在第四个框架发布之前,这种注入方法存在很大的问题–方面要求使用默认构造函数。 现在仍然存在基于构造函数的注入的“缺点”:它不允许循环依赖。 我特意在双引号中添加了缺点,因为对我来说,这是该机制的巨大优势:)文档中还有另外一句话:

通常建议不要在您的bean之间使用循环引用。

但为什么? 如果我们的应用程序中有循环引用,该怎么办? 我不想写有关应用程序设计的文章,因为几乎总是可以重构我们的代码并将有问题的逻辑委托给第三个bean。 有两个重大而不幸的“沉默”问题。

第一个陷阱

调用ListableBeanFactory.getBeansOfType()方法时,不能确定将返回哪些Bean。 让我们看一下DefaultListableBeanFactory类的代码:

if (isCurrentlyInCreation(bce.getBeanName())) {if (this.logger.isDebugEnabled()) {this.logger.debug("Ignoring match to currently created bean '"+ beanName + "': " + ex.getMessage());}// ...continue;
}

如您所见,如果您不使用DEBUG日志记录级别,那么将有零个信息表明Spring在解析过程中跳过了特定的bean。 如果您想获取所有事件处理程序,那就太麻烦了:)

第二陷阱

第二个问题涉及AOP。 如果要在bean上使用方面,请确保它不涉及循环引用-否则Spring将创建bean的两个实例–一个没有方面,另一个具有适当方面。 当然仍然没有任何信息。 惊讶吗

对我来说, 停止在我们的应用程序中使用循环依赖就足够了(特别是与此相关的行为可能更有趣)。

请勿使用循环依赖!

但是,我们该如何摆脱困境呢? 当然,您可以使用基于构造函数的注入:)但是,如果您拥有大量应用程序,那么花很多时间重写所有类以使用构造函数而不是setter并不是最好的主意。 幸运的是,我有个好消息– AbstractRefreshableApplicationContext类中的allowCircularReferences字段。 只需添加一行到应用程序上下文创建(所描述的方式在这个岗位 )

AnnotationConfigWebApplicationContext applicationContext =new AnnotationConfigWebApplicationContext();
applicationContext.setAllowCircularReferences(false);
// rest of context initialization

最后,为了使您心情愉快,我从DefaultListableBeanFactory粘贴了另一个代码片段:

catch (NoSuchBeanDefinitionException ex) {// Shouldn't happen - probably a result of circular reference resolution...if (logger.isDebugEnabled()) {logger.debug("Failed to check manually registered singleton with name '"+ beanName + "'", ex);}
}

祝你今天愉快! :)

翻译自: https://www.javacodegeeks.com/2015/01/dependency-injection-pitfalls-in-spring.html

spring依赖注入

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/339004.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言中的“悬空指针”和“野指针”是什么意思?

提起C语言大部分开发者很自然就会想到指针二字,没错,作为C的核心和灵魂,它的地位咱们就不再赘述了,今天我们想跟大家讲的是指针中的两个特有名词:“悬空指针”和“野指针”。1 悬空指针C语言中的指针可以指向一块内存&…

java zip解压_Java语言入门第一课

Java最初的目标是嵌入式设备,不过在嵌入式设备方面并未取得成功。失之东隅,收之桑榆,Java却在Web领域被广泛接受。近年来,随着Java在服务器领域的不断突破,让这门语言越来越流行。有人喜欢Java的纯面向对象&#xff0c…

怎么用c语言做出等妖三角形_初二数学培优,怎么用顶点坐标求三角形面积?割补法这样用很简单...

点击右上角关注“陈老师初中数理化”分享学习经验,一起畅游快乐的学习生活。根据顶点坐标求解三角形的面积是初二数学的重要知识点,本文就例题详细解析这类题型的解题思路,希望能给初二学生的数学学习带来帮助。例题如图,在平面直…

restful xml_使用入站适配器公开HTTP Restful API。 第1部分(XML)

restful xml1.简介 这篇文章的目的是使用Spring Integration HTTP入站适配器实现HTTP Restful API。 本教程分为两个部分: XML配置示例(同一篇文章)。 Java DSL示例。 这将在本教程的下一部分中进行说明,展示如何使用Spring Int…

C语言的位域

位域是什么?有些数据在存储时并不需要占用一个完整的字节,只需要占用一个或几个二进制位即可。例如开关只有通电和断电两种状态,用 0 和 1 表示足以,也就是用一个二进位。正是基于这种考虑,C语言又提供了一种叫做位域的…

xp精简工具_办公人士需要精简Win10吗?

首先要说自己的系统需求1,笔记本是主要生产力工具,靠它做方案,联系网络社交;2,会偶尔(一月2-3次)用到PS,AI,PR等软件;3,文件多,版本多…

matlab 删除路径_MATLAB使用教程(一)—新手来看

前言:在这里,本人默认大家已经安装好了MATLAB软件,如果没有,请自行安装。注意事项:新手容易犯错,打开MATLAB之后,请按CTRLQ这个组合键,是不是发现你的MATLAB关闭了?对&am…

数据的gzip压缩解压缩_使用GZIP和压缩数据

数据的gzip压缩解压缩抽象 我们都知道用zip或gzip压缩文件的含义。 但是在Java中使用压缩文件并不像您想的那样简单,特别是如果您不是直接使用文件而是压缩流数据时。 我们会去: 如何将字符串转换为压缩/压缩字节数组,反之亦然 创建用于读取…

C语言开发单片机为啥都是全局变量形式?

01前言全局变量简直就是嵌入式系统的戈兰高地。冲突最激烈的双方是:1. 做控制的工程师;2. 做非嵌入式的软件工程师。02做控制的工程师特点他们普遍的理解就是“变量都写成全局该有多方便”。我之前面试过一个非常有名的做控制实验室里出来的PhD/Master&a…

ajax get请求_python测试开发django50.jquery发送Ajax请求(get)

前言有时候,我们希望点击页面上的某个按钮后,不刷新整个页面,给后台发送一个请求过去,请求到数据后填充到html上,这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。Ajax可以完美的实现。…

primefaces_PrimeFaces Mobile入门

primefaces介绍 如果您已经开发了利用PrimeFaces的应用程序,或者打算开发可在台式机和移动设备上使用的Web应用程序,请考虑将PrimeFaces Mobile用于您的移动实施。 这篇博客文章将介绍一些基础知识,以帮助您开始为现有的PrimeFaces应用程序开…

C语言指针这些使用技巧值得收藏!

指针用的好犹如神助,用不好会让你叫苦连连,但大多数人是用不好指针的,所以后来的很多语言都把指针封装,屏蔽。比如JAVA,java是没有指针的,但是很多地方都用到指针,不过不对用户开放,…

如何用python实现地图定位_基于 PyQt5 实现地图中定位相片拍摄位置

项目简介:本次项目主要学习了如何查找相片中的 Exif 信息,并通过 Exif 信息中的 GPS 数据在百度地图中进行定位标点,以确定相片的拍摄地点。本次实验的目的旨在通过包含 GPS 信息的相片进行取证调查,当然个人娱乐也可以&#xff0…

mysql数据库中的int类型_MySQL中int(M)和tinyint(M)数值类型中M值的意义

在一开始接触MySQL数据库时,对于int(M)及tinyint(M)两者数值类型后面的M值理解是最多能够插入数据库中的值不能大于M;后来工作后,也是一边学习一边使用,之后的理解是其中的M的意思是插入数据库中的值的字符长度不能大于M&#xff…

arquillian_使用Arquillian测试安全的EJB

arquillian从历史上讲,很难测试安全的EJB。 到目前为止,我一直在使用专有技术(如JBossLoginContextFactory)中所述的文章( 使用Arquillian在WildFly 8.1.x上测试安全的EJB)来测试安全的EJB。 在今年Devoxx…

api怎么写_使用Node.js原生API写一个web服务器

Node.js是JavaScript基础上发展起来的语言,所以前端开发者应该天生就会一点。一般我们会用它来做CLI工具或者Web服务器,做Web服务器也有很多成熟的框架,比如Express和Koa。但是Express和Koa都是对Node.js原生API的封装,所以其实不…

C语言预处理命令分类和工作原理

C语言编程过程中,经常会用到如 #include、#define 等指令,这些标识开头的指令被称为预处理指令,预处理指令由预处理程序(预处理器)操作。相比其他编程语言,C/C 语言更依赖预处理器,故在阅读或开…

查看mysql用户权限_mysql 如何查看该数据库用户具有哪些权限?

展开全部背景在了解动态权限之前,我们先回顾下 MySQL 的权限列表。权限列表大体分为服务级别和表级别,列级别以32313133353236313431303231363533e59b9ee7ad9431333433633464及大而广的角色(也是MySQL 8.0 新增)存储程序等权限。我们看到有一个特殊的 SU…

注释嵌套注释_注释,无处不在的注释

注释嵌套注释十年前的2004年 , Java 1.5开始提供注释。 很难想象没有此功能的代码。 实际上,首先引入了注释,以减轻开发人员编写繁琐的样板代码的痛苦,并使代码更具可读性。 考虑一下J2EE 1.4(没有可用的注释&#xff…

a标签跳到另一个页面指定选项卡_HTML常用标签

本篇文章主要是对a、img和table标签用法介绍:a标签:可称为锚元素,主要功能是创建通向其他网页、文件、同一页面的其他位置、电子邮件地址或其他任何url地址的超链接;1.img标签:发出get请求并显示返回的图片1.常用属性&…