spring-core-2-20 | 构造器注入 VS. Setter 注入:为什么Spring官方文档的解读会与作者的初心出现偏差

Spring (5.2.22.RELEASE)源码编译问题总结+成功编译 没有编译Sping boot源码之前听说很难,然后做好了嗑好几天的准备,然后自己尝试的时候,其实也就那样了,很简单,总体大概就花了一个下午,所以不要被别人口中的困难吓到,勇于尝试才是真理...... 阅读详情

构造器注入VS. Setter 注入

Spring Framework 对构造器注入与Setter 的论点:

来自“Constructor-based or setter-based DI”

“The Spring team generally advocates constructor injection, as it lets
you implement application components as immutable objects and ensures that required dependencies are not null.

Furthermore, constructor-injected components are always returned to the client (calling) code in a fully initialized state. As a side note, a large number of constructor arguments is a bad code smell, implying that the class likely has too many responsibilities and should be refactored to better address proper separation of concerns.

Setter injection should primarily only be used for optional dependencies that can be assigned reasonable default values within the class. Otherwise, not-null checks must be performed everywhere the code uses the dependency. One benefit of setter injection is that setter methods make objects of that class amenable to reconfiguration or re-injection later.
Management through JMX MBeans is therefore a compelling use case for setter injection.”

这里spring团队以一个讨论的口吻来说的, 建议一般使用构造器注入, 保证注入的对象是一个immutable, 不变的对象, 确保依赖的对象不为空. 这个讲法忽略了一个细节, 其实如果依赖的对象为空或者不存在的话, 可以用另外的方式, 也可以通过构造器方式进行注入, 使用 ObjectProvider 类, 它是一种类型安全的方式, 如果你的依赖注入或依赖查找的方式需要的是一个单一类型的依赖, 这时可以调用它的 getIfAvailable() ,来进行示范性的返回, 等于空的时候就会返回空, 这种方式在 springBoot的场景中经常被用到.

构造器注入的组件通常返回给客户端代码的时候, 是一个完整的初始化状态. 不过呢, 如果构造器的参数过多, 代码看起来就不是十分的良好, 意味着类包含了太多的职责, 不能有太多的输入, 最好进行一下重构(refactored)

Setter注入应该主要仅用于我们的可选性的注入, 另一方面, 如果代码中有用到相关的依赖, 非空检查就是必须的, 我们都知道@Autowired注解是有非空检查的参数的, 而默认可以注入空的对象过来.当然 Setter 注入可以让依赖进行延迟注入, 让对象变得更可配, 这是一个优点

《Expert One-on-One™ J2EE™ Development without EJB™》认为Setter 注入的优点:

来自“Chapter 6. Lightweight Containers and Inversion of Control” 节选

“Advantages of Setter Injection include:

• JavaBean properties are well supported in IDEs.
JavaBean的属性在IDE方面支持良好, 前面讲过, 在 GUI 方面是有用的.

• JavaBean properties are self-documenting.
JavaBean的属性是 自文档 的方式, 通常不需要过多文档说明

• JavaBean properties are inherited by subclasses without the need for any code.
JavaBean的属性通过继承的方式呢, 通常不需要任何的修改, 但是这个通常不应该是个优点, 只是作为面向对象的一个特点

• It’s possible to use the standard JavaBeans property-editor machinery for type conversions if necessary.
因为有 propertyEditor 这个机制, setter中可以进行一些类型转换

• Many existing JavaBeans can be used within a JavaBean-oriented IoC
container without modification.
大量存在的JavaBeans可以在JavaBean原生的IoC容器中使用, 不需要做太大的修改.
这里就是指的原生的 BeanContext 这个容器, 这个上下文其实和 spring的 ApplicationContext 有异曲同工之处.

• If there is a corresponding getter for each setter (making the property readable, as well as writable), it is possible to ask the component for its current configuration state. This is particularly useful if we want to persist that state: for example, in an XML form or in a database. With Constructor Injection, there’s no way to find the current state.
如果每一个Setter方法都有对应的Getter方法的情况下, 可以比较方便的在任何时候获取到组件的当前状态.这个特点在我们需要保存这个状态的时候特别有用, 而构造器注入就做不到这点. 这样就容易对Bean进行一个管理.

• Setter Injection works well for objects that have default values, meaning that not all properties need to be supplied at runtime.
Setter方法可以为属性设置一个默认值, 并不是所有的属性都需要在运行时才进行设值.

《Expert One-on-One™ J2EE™ Development without EJB™》认为Setter 注入的缺点:

来自“Chapter 6. Lightweight Containers and Inversion of Control” 节选

“Disadvantages include:

The order in which setters are called is not expressed in any contract. Thus, we sometimes need to invoke a method after the last setter has been called to initialize the component. Spring provides the org.springframework.beans.factory.InitializingBean interface for
this; it also provides the ability to invoke an arbitrary init method. However, this contract must be documented to ensure correct use outside a container.
setter的顺序无法保证, 而构造器注入因为构造器方法的参数顺序是一定的, 天然决定了设值的顺序是有序的, 不会因为外部调用的顺序而出现问题.
这里提到了一个spring的接口 InitializingBean ,这个接口能够帮助我们实现一个特性就是当我的属性已经设置好了之后, 我们再做相应的操作. 但是这个接口并不会强制的保证正确性, 只是一个鼓励.

Not all the necessary setters may have been called before use. The object can thus be left partially configured.”
在调用前并不是每一个Setter方法都需要被调用的.

《Expert One-on-One™ J2EE™ Development without EJB™》认为构造器注入的优点:

来自“Chapter 6. Lightweight Containers and Inversion of Control” 节选

“Advantages of Constructor Injection include:

Each managed object is guaranteed to be in a consistent state—fully configured—before it can be invoked in any business methods. This is the primary motivation of Constructor Injection. (However, it is possible to achieve the same result with JavaBeans via dependency checking, as Spring can optionally perform.) There’s no need for initialization methods.
能够确保每个被管理的对象有一致的状态. 完全配置好的, 且一旦初始化完成就不再进行变更的. 正如前面所说, 也因此组件对应的对象通常也被声明为 final 的.

There may be slightly less code than results from the use of multiple JavaBean methods, although will be no difference in complexity.”
减少过多的Setter和Getter方法的代码量. 这个因为现在有建造模式, 似乎也没啥必要.

《Expert One-on-One™ J2EE™ Development without EJB™》认为构造器注入的缺点:

来自“Chapter 6. Lightweight Containers and Inversion of Control” 节选
这里就能看到, 作者一开始书里的观点, 和后来在spring官方网站的观点, 有一些冲突, 这里反而构造器注入的缺点列了一大堆.

“Disadvantages include:

• Although also a Java-language feature, multi-argument constructors are probably less common in existing code than use of JavaBean properties.
多参数构造器可能会减少代码中一些Bean的使用. 啥意思?

• Java constructor arguments don’t have names visible by introspection.
构造器参数没有一个名称是可见的来提供给外部进行外省或内省.

• Constructor argument lists are less well supported by IDEs than JavaBean setter methods.
IDE的支持不如Setter方法的好

• Long constructor argument lists and large constructor bodies can become
unwieldy.

• Concrete inheritance can become problematic.

• Poor support for optional properties, compared to JavaBeans

• Unit testing can be slightly more difficult

• When collaborators are passed in on object construction, it becomes
impossible to change the reference held in the object. ”

Python 爬虫:获取网页数据的 5 种方法 requests:适用于简单的静态网页抓取,易于使用。requestslxml:适合需要高效解析大规模网页内容的情况,支持 XPath 和 CSS 选择器。Selenium:适用于动态网页(JavaScript 渲染)的抓取,模拟浏览器行为获取动态数据。Scrapy:强大的爬虫框架,适合大规模的网页抓取任务,支持异步请求和高级功能。PyQuery:基于 jQuery 语法,适合快速开发,提供简洁的 CSS 选择器语法。 阅读详情

相关推荐

告别Keil?在Mac上配置STM32CubeIDE + CMSIS-DAP调试器全攻略(含常见报错解决)

本文详细介绍了在Mac平台上配置STM32CubeIDE与CMSIS-DAP调试器的全流程,包括硬件准备、软件安装、工程创建及调试优化。通过实战指南,帮助开发者高效完成STM32开发,解决常见报错问题,提升开发效率。

weixin_30485379的博客 433

Spring的三种注入方式详解_官方推荐构造器注入

今天在看项目代码的时候发现在依赖注入的时候使用了构造器注入,之前使用过 Field 注入和 Setter 方法注入,对构造器注入不是很了解。经过查阅资料看到,Spring 推荐使用构造器注入的方式,下面介绍构造器注入到底有什么玄机。...

Eliauk4的博客 1万+

uni-app项目中引入Vant UI组件库(完美避坑!!!)纯净版

uni-app项目中引入Vant UI组件库(纯净版--无uni-ui)

Wzmlzrr的博客 3万+

spring5.2.20源码搭建报错问题

spring源码搭建解决aspectj报错问题

贤_龍的博客 760

树莓派烧录验证失败:跳过验证步骤实现成功启动的实用技巧

本文针对树莓派烧录系统时常见的验证失败问题,提供了跳过验证步骤实现成功启动的实用技巧。通过分析Windows与Linux文件系统差异导致的SD卡验证报错,指导用户在烧录完成后立即关闭验证窗口,或使用BalenaEtcher等第三方工具规避问题,确保树莓派正常启动。

yyy34的博客 949

OpenClaw-遇到的问题- FailoverError: Model context window too small (4096 tokens). Minimum is 16000

摘要:OpenClaw配置文件中deepseek-reasoner模型的上下文窗口被默认设置为4096 tokens(实际支持128K),导致系统报错"Model context window too small"。解决方案是删除配置文件中的contextWindow和maxTokens字段,让系统自动获取模型真实能力,并重启OpenClaw服务。配置文件通常位于用户目录下的.openclaw/openclaw.json中。

直到世界的尽头 4157

Spring的setter方法注入和构造器注入的对比

setter方法注入构造器注入不可变对象无法设置为不可变可以按需设置为不可变确保所需的依赖非空无法确保可以确保代码异味(类被注入了太多对象)不容易识别很容易识别注意:对于“所需的依赖为空”的情况,也分具体情况,比如通过@Autowired给setter方法注入对象,如果找不到满足条件的类(byType),默认情况下会报错,详见我另一篇文档。所以,通过对比,我们得出结论:构造器注入就是好!...

duke_ding2的博客 3029

在armv8架构中,有哪些是serror

(3)、RAS(Reliability, Availability, and Serviceability)错误:一些对于系统的可靠性、可用性和可维护性有影响的错误可能会触发 SError。(2)、ECC(Error Correction Code)错误:在访问带有错误校验的内存(如ECC内存)时,如果发现错误校验失败,可能会产生SError。2、其实呢,大多数Serror都是实现定义的,真正实现的serror就没有多少个。Serror(也称System Error),是异步异常的一种,一般是来自。

baron-周贺贺-代码改变世界ctw 1013

关于依赖注入中setter注入和构造器注入的区别的思考

依赖注入Setter注入和构造器注入的区别

m0_46827210的博客 1324

基于MATLAB的奇异谱分析(SSA)算法详解

本文详细介绍了基于MATLAB的奇异谱分析(SSA)算法。文章首先阐述了SSA的基本概念、历史发展及其与传统信号分析方法的对比优势,指出SSA作为一种非参数、非线性时间序列分析方法,特别适合处理非平稳信号。随后详细解析了SSA算法的核心原理与数学模型,包括轨迹矩阵构建、奇异值分解、分组与重构四个关键步骤。文章还提供了完整的MATLAB实现框架和代码解析,涵盖参数检查、轨迹矩阵构建、SVD分解、分组策略和重构过程。最后,通过信号分解、去噪和预测三个应用案例展示了SSA的实际效果。

qq_42212808的博客 168

计算机视觉学习路线图:从入门到专家

计算机视觉学习路线图:从入门到专家​ ,人工智能,计算机视觉,大模型,AI,计算机视觉学习路线图从七方面展开。先强调数学基础,含线性代数、概率统计和微积分;接着介绍 Python、OpenCV 等编程语言与工具;涵盖边缘检测、特征提取等经典算法;阐述深度学习中 CNN 结构、经典模型及实现;涉及目标检测、图像分割等高级专题;包含图像分类、目标检测和人脸识别等项目实战;最后提及科研进阶的论文阅读、项目参与和论文发表,助学习者从入门到专家。

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 7万+

Spring依赖注入方式,为什么Spring4.0提倡使用构造函数注入方式?

先回答题目中的问题: 基于构造函数或基于setter的DI? 何时使用构造注入,何时使用setter注入,经验法则是:强制依赖用构造,可选依赖用Setter。注意,在settter方法上使用@Required注解即可令属性强制依赖。  Spring 团队建议,构造注入的实例是不可变的,不为null的。此外,构造注入组件要将完全初始化后的实例返回给客户端代码。还有,大量参数的构造函数是非常烂的,...

程序员野蛮成长 1449

机器人视觉联动精度优化:从±2mm到±0.02mm,产线级手眼标定全实战

2025年我接东莞长安Type-C接口分拣项目的时候,就是栽在了手眼标定上:实验室里标定完精度±0.5mm,一到产线直接掉到±2mm,机器人10次有3次抓不住,2000多件Type-C接口直接报废,还撞坏了2套汇川SCARA机器人的吸盘,本来45天的工期拖了3个月,不仅没赚到钱,还倒贴了几万块。手眼标定从来不是简单的跑个demo、算个矩阵就完事了,它是一个系统工程:从硬件选型、安装固定、相机标定、标定流程、算法优化、环境控制、重复验证,每一个环节都会影响最终的联动精度。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 384

第十二章 spring依赖注入概述与 constructor-based dependencyinjection和setter-based dependency injection 类型

概述 每个基于应用程序的Java都有几个对象,这些对象一起工作来呈现出终端用户所看到的工作的应用程序。当编写一个复杂的Java应用程序时,应用程序类应该尽可能独立于其它Java类用增加这些重用的可能性。依赖注入(或有时称为布线)有助于把这些类粘合在一起,同时保持他们独立。 类型 constructor-based dependencyinjection 当容器调用带有多个参数的构造函数类时,实现基于构造函数的DI每个代表在其它类中的一个依赖关系。 setter-based dependency inject

weixin_44560521的博客 280

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

spring学习之路2 - spring-core

spring core下有6个包 asm 提供了web 的基本操作 lang 提供了java 语言不同版本兼容的功能. Objenesis 实例化对象的方式. util 提供了 compare, backoff, xml, concurrent, MimeType 的方式. cglib core 提供了基本核心模块IO/serial,codec,convert,env 等. Spring Core - 简书 1、基础设施工具类(spring框架基...

yiguang_820的博客 4246

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Spring构造注入时参数异常Could not resolve matching constructor (hint: specify index/type/name arguments for s

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'student' defined in class path resource [ApplicationContext.xml]: Could not resolve matching constructor (hint: ...

jack_zhs的博客 7131

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

重新认识 IoC

IoC 发展简介 什么是 IoC ? In software engineering, inversion of control (IoC) is a programming principle. IoC inverts the flow of control as compared to traditional control flow. In IoC, custom-written portions of a computer program receive the flow of control fr

通往神秘的道路的专栏 584

java setter 注入_setter(设置)注入和构造注入区别

在过去的开发过程中,这两种注入方式都是非常常用的。Spring也同时支持两种依赖注入方式:设置注入和构造注入。 这两种依赖注入的方式,并没有绝对的好坏,只是适应的场景有所不同。相比之下,设置注入有如下优点:1.设置注入需要该Bean包含这些属性的setter方法2.与传统的JavaBean的写法更相似,程序开发人员更容易理解、接收。通过setter方法设定依赖关系显得更加直观。3.对于复杂的依赖关...

weixin_31261145的博客 1364

Spring Framework 总结和面试题

核心特性(Core) IoC容器(IoC Container) Spring事件(Events) 资源管理(Resources) 国际化(i18n) 校验(Validation) 数据绑定(Data Binding) 类型转换(Type Conversion) Spring表达式(Spring Express Language) 面向切面编程(AOP) 数据存储(Data Access) JDBC 事务抽象(Transactions) DAO支持(DAO Support)

vincent_wen0766的博客 1038

Spring的两种依赖注入方式:setter方法注入与构造方法注入

Spring的两种依赖注入方式:setter注入与构造方法注入,这两种方法的不同主要就是在xml文件下对应使用property和constructor-arg属性, 例如: property属性:(其中name的值为原类中的属性名) constructor-arg属性:(其中index的值为0~n-1,n代表构造函数中的输入参数的数量) 1.setter方法注入    se

loster_Li的博客 9605

Spring - 面试题(一)

IOC和DI是什么? IoC (Inversion of Control) 控制反转什么是控制反转? 控制反转是就是应用本身不负责依赖对象的创建和维护,依赖对象的创建及维护是由外部容器负责的,这样控制权就有应用转移到了外部容器,控制权的转移就是控制反转。 DI (Dependency Injection) 依赖注入什么是依赖注入? 依赖注入是指:在程序运行期间,由外部容器动态地将依赖对象注入到组件中 如:一般,通过构造函数注入或者setter注入。 Spring IOC 的理解,其初始化过程?

Pastxu的小屋 879

spring-setter注入(属性和构造器注入)

<!--setter注入: 不关注类是否存在这个属性,只关注是否存在这个setter方法,setter方法名称为set拼上property的name首字母大写,并将后面的值赋给setter方法中的形参--> <!-- bean下面property的ID首字母大写,前面拼上set,形成setter方法,在该bean中必须存在。--> <!-- value是后面形参变量的值--> <bean id="student" class=".

qq_41275474的博客 783

依赖注入的两种常用方式(构造器和Setter)与注入内容(装配数据)——Spring IOC/DI(三)

本章主要讲解一下基本用法,原理就不讲了,接上一章依赖注入原理和方式: 依赖注入常用的两种方式 Spring通过DI(依赖注入)实现IOC(控制反转),常用的注入方式主要有三种:构造方法注入,setter注入和接口注入。 本章重点讲解基本的两种方式构造器和setter,注解后面会单独一章讲解 案例准备 创建ApplicationContext.xml作为Spring配置文件: &amp;amp;amp;amp;amp;amp;amp;lt;?xml v...

方圆几里 6298

setter(设置)注入和构造注入区别

在过去的开发过程中,这两种注入方式都是非常常用的。Spring也同时支持两种依赖注入方式:设值注入和构造注入。 这两种依赖注入的方式,并没有绝对的好坏,只是适应的场景有所不同。相比之下,设值注入有如下优点: 1.设值注入需要该Bean包含这些属性的setter方法 2.与传统的JavaBean的写法更相似,程序开发人员更容易理解、接收。通过setter方法设定依赖关系显得更加只管。 3.对于复杂的...

qq_42532423的博客 3674

Intellij IDEA 如何去掉 @Autowired 注入警告

Intellij IDEA 如何去掉 @Autowired 注入警告

飘渺Jam的博客 1万+

狂神说Spring04:自动装配

Bean的自动装配 自动装配说明 自动装配是使用spring满足bean依赖的一种方法 spring会在应用上下文中为某个bean寻找其依赖的bean。 Spring中bean有三种装配机制,分别是: 在xml中显式配置; 在java中显式配置; 隐式的bean发现机制和自动装配。 这里我们主要讲第三种:自动化的装配bean。 Spring的自动装配需要从两个角度来实现,或者说是两个操作: 组件扫描(component scanning):sp

byteyoung 611
上一篇: spring-core-2-19 | 依赖查找 VS. 依赖注入:为什么Spring总会强调后者,而选择性忽视前者?
下一篇: spring-core-3-22 | Spring IoC依赖查找:依赖注入还不够吗?依赖查找存在的价值几何?
sunforraining
博客等级 码龄9年 13粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值