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

为什么Spring官方推荐使用构造方法进行依赖注入 为什么Spring官方推荐使用构造方法进行依赖注入 一、前言 我们在使用Spring框架进行开发时,不可避免的要进行依赖注入(Dependency Injection),也就是把实例从Spring容器中取出来进行使用。Spring的依赖注入方式主要有三种,分别为Constructor、Setter和Field。 二、方法对比 Field注入 @Autowired private DependencyA dependencyA; 优点 注入简单,只需在字段上添加@Autowired或@Resource; 阅读详情

先回答题目中的问题:

基于构造函数或基于setter的DI?

何时使用构造注入,何时使用setter注入,经验法则是:强制依赖用构造,可选依赖用Setter。注意,在settter方法上使用@Required注解即可令属性强制依赖。 
Spring 团队建议,构造注入的实例是不可变的,不为null的。此外,构造注入组件要将完全初始化后的实例返回给客户端代码。还有,大量参数的构造函数是非常烂的,它意味着该类有大量的职责,得重构。 
setter注入主要用于可选依赖,类内部可以指定默认依赖。否则类内所有使用依赖的地方,都得进行非空校验。setter注入的有个好处就是,类可以重配置或者再注入。因此,使用JMXMBeans进行管理的场景中,就非常适合setter注入。 
使用何种依赖注入方式,对于某些类,非常有意义。有时协同第三方类处理,没有源码,由你来决定使用何种方式。比如,第三方类未暴露任何setter方法,那么构造注入也许就是唯一的可行的注入方式了。

官网原文:

Constructor-based or setter-based DI?

Since you can mix constructor-based and setter-based DI, it is a good rule of thumb to use constructors for mandatory dependencies and setter methods or configuration methods for optional dependencies. Note that use of the @Required annotation on a setter method can be used to make the property a required dependency.

The Spring team generally advocates constructor injection as it enables one to implement application components as immutable objects and to ensure that required dependencies are not null. Furthermore constructor-injected components are always returned to 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.

Use the DI style that makes the most sense for a particular class. Sometimes, when dealing with third-party classes for which you do not have the source, the choice is made for you. For example, if a third-party class does not expose any setter methods, then constructor injection may be the only available form of DI.

 

下面详细讲述下依赖注入:

依赖注入(DI)是一个过程,通过这个过程,对象定义它们的依赖关系,即它们使用的其他对象,只能通过构造函数参数,工厂方法的参数或在构造或返回对象实例后在对象实例上设置的属性。从工厂方法。然后容器在创建bean时注入这些依赖项。这个过程基本上是反向的,因此名称 Inversion of Control(IoC),bean本身通过使用类的直接构造或服务定位器模式来控制其依赖项的实例化或位置。

使用DI原理的代码更清晰,当对象提供其依赖项时,解耦更有效。该对象不查找其依赖项,也不知道依赖项的位置或类。因此,您的类变得更容易测试,特别是当依赖关系在接口或抽象基类上时,这允许在单元测试中使用存根或模拟实现。

DI存在两个主要变体,基于构造函数的依赖注入和基于Setter的依赖注入。

基于构造函数的依赖注入

基于构造函数的 DI由容器调用具有多个参数的构造函数来完成,每个参数表示一个依赖项。调用static具有特定参数的工厂方法来构造bean几乎是等效的,本讨论同样处理构造函数和static工厂方法的参数。以下示例显示了一个只能通过构造函数注入进行依赖注入的类。请注意,此类没有什么特别之处,它是一个POJO,它不依赖于容器特定的接口,基类或注释。

public  class SimpleMovieLister {

    // SimpleMovieLister依赖于MovieFinder 
    私有 MovieFinder movieFinder;

    //一个构造函数,以便Spring容器可以注入一个MovieFinder 
    public SimpleMovieLister(MovieFinder movieFinder){
         this .movi​​eFinder = movieFinder;
    }

    //省略了实际使用注入的MovieFinder的业务逻辑... 

构造函数参数解析

使用参数的类型进行构造函数参数解析匹配。如果bean定义的构造函数参数中不存在潜在的歧义,那么在bean定义中定义构造函数参数的顺序是在实例化bean时将这些参数提供给适当的构造函数的顺序。

package x.y;

public class Foo {

    public Foo(Bar bar, Baz baz) {
        // ...
    }
}

假设Bar并且Baz类与继承无关,则不存在潜在的歧义。因此,以下配置工作正常,您不需要在<constructor-arg/> 元素中显式指定构造函数参数索引和/或类型。

<beans>
    <bean id="foo" class="x.y.Foo">
        <constructor-arg ref="bar"/>
        <constructor-arg ref="baz"/>
    </bean>

    <bean id="bar" class="x.y.Bar"/>

    <bean id="baz" class="x.y.Baz"/>
</beans>

当引用另一个bean时,类型是已知的,并且可以进行匹配(与前面的示例一样)。当使用简单类型时,例如 <value>true</value>,Spring无法确定值的类型,因此无法在没有帮助的情况下按类型进行匹配。

package examples;

public class ExampleBean {

    // Number of years to calculate the Ultimate Answer
    private int years;

    // The Answer to Life, the Universe, and Everything
    private String ultimateAnswer;

    public ExampleBean(int years, String ultimateAnswer) {
        this.years = years;
        this.ultimateAnswer = ultimateAnswer;
    }
}

在前面的场景中,如果使用属性显式指定构造函数参数的类型,则容器可以使用与简单类型匹配的类型type。

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg type="int" value="7500000"/>
    <constructor-arg type="java.lang.String" value="42"/>
</bean>

使用该index属性显式指定构造函数参数的索引。

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg index="0" value="7500000"/>
    <constructor-arg index="1" value="42"/>
</bean>

除了解决多个简单值的歧义之外,指定索引还可以解决构造函数具有相同类型的两个参数的歧义。请注意, 索引基于0。

您还可以使用构造函数参数名称进行值消歧:

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg name="years" value="7500000"/>
    <constructor-arg name="ultimateAnswer" value="42"/>
</bean>

请记住,要使这项工作开箱即用,必须在启用调试标志的情况下编译代码,以便Spring可以从构造函数中查找参数名称。如果无法使用debug标志编译代码(或者不希望),则可以使用 @ConstructorProperties JDK批注显式命名构造函数参数。然后,示例类必须如下所示:

package examples;

public class ExampleBean {

    // Fields omitted

    @ConstructorProperties({"years", "ultimateAnswer"})
    public ExampleBean(int years, String ultimateAnswer) {
        this.years = years;
        this.ultimateAnswer = ultimateAnswer;
    }
}

基于Setter的依赖注入

基于setter的 DI是在调用无参数构造函数或无参数static工厂方法来实例化bean之后,通过容器调用bean上的setter方法来完成的。

以下示例显示了一个只能使用纯setter注入进行依赖注入的类。这个类是传统的Java。它是一个POJO,它不依赖于容器特定的接口,基类或注释。

public  class SimpleMovieLister {

    // SimpleMovieLister依赖于MovieFinder 
    私有 MovieFinder movieFinder;

    //一个setter方法,以便Spring容器可以注入一个MovieFinder 
    public  void setMovieFinder(MovieFinder movieFinder){
         this .movi​​eFinder = movieFinder;
    }

    //省略了实际使用注入的MovieFinder的业务逻辑... 
}

该ApplicationContext支架构造和基于setter方法的DI为它所管理的豆类。在通过构造函数方法注入了一些依赖项之后,它还支持基于setter的DI。您可以以a的形式配置依赖项,并将BeanDefinition其与PropertyEditor实例结合使用,以将属性从一种格式转换为另一种格式。然而,大多数Spring用户不直接与这些类(即,编程),而是用XML bean 定义,注释组件(即与注释类@Component, @Controller等等),或@Bean在基于Java的方法@Configuration类。然后,这些源在内部转换为实例BeanDefinition并用于加载整个Spring IoC容器实例。

 

Spring官网原文地址:https://docs.spring.io/spring/docs/4.3.20.RELEASE/spring-framework-reference/htmlsingle/#beans-constructor-injection

关于Spring依赖注入的几种方式 今天在开发的过程中,突然对Spring的依赖注入几种方式出现混交,打算做个简单的小结,如有总结不对的地方,请大家不吝指教!在Spring中依赖注入有四种方式:set注入(通常也叫属性注入),构造函数注入,接口注入(这个现在基本不用),注解注入(@Autowire),下面对set方法注入,构造函数注入,以及注解注入的用法举例说明。1、set方法注入(属性注入) UserDao.javapublic 阅读详情

相关推荐

Spring-IOC的依赖注入的三种方式-使用构造函数提供+使用set方法提供+使用注解提供+混合使用

Spring-IOC的依赖注入 通过控制反转,把对象的创建交给了 spring,但是代码中不可能出现没有依赖的情况。ioc解耦只是降低他们的依赖关系,但不会消除。 例如:我们的业务层仍会调用持久层的方法。 那这种业务层和持久层的依赖关系,在使用 spring 之后,就让 spring 来维护了。 简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取。 通过控制反转,把对象的创建交给了 spring,但是代码中不可能出现没有依赖的情况。ioc解耦只是降低他们的依赖关系,但不会消除。 例如:我们的

weixin_44325370的博客 983

Spring - 依赖注入:构造函数注入、set方法注入和注解注入

1.2 依赖注入(Dependency Injection) 依赖注入的数据类型: 基本类型和String类型 bean类型 复杂类型/集合类型 依赖注入的三种方式: 使用构造函数提供 使用set方法提供 使用注解方式提供 1.2.1 通过构造函数实现依赖注入 当java类中写了自己的构造函数(如下面所给代码,构造函数有三个参数),则...

hugh___的博客 3960

Spring依赖注入方式选择:全面解析

依赖注入是一种设计模式,用于实现控制反转(Inversion of Control, IoC)。它通过将对象的依赖关系从代码中分离出来,改为由外部容器在运行时注入,从而实现对象之间的松耦合。构造器注入是通过构造器参数传递依赖对象。这种方式在创建对象时,必须提供所有依赖对象,适用于必须的依赖关系。设值方法注入是通过Setter方法传递依赖对象。这种方式在创建对象后,可以通过Setter方法动态地注入依赖对象,适用于可选的依赖关系。字段注入是通过直接在字段上添加注解来注入依赖对象。

xycxycooo的博客 1237

spring中的依赖注入——构造函数注入、set方法注入( 更常用的方式)、复杂类型的注入/集合类型的注入

spring中的依赖注入 依赖注入: Dependency Injection IOC的作用:降低程序间的耦合(依赖关系) 依赖关系的管理:以后都交给spring来维护。在当前类需要用到其他类的对象,由spring为我们提供,我们只需要在配置文件中说明 依赖关系的维护:就称之为依赖注入 依赖注入: 能注入的数据:有三类 基本类型和String ...

qq_39368007的博客 654

DPABI安装教程

DPABI是是中科院心理研究所严超赣老师团队开发的一款磁共振脑影像数据分析工具包。基于SPM,在安装DPABI之前需要安装好SPM,才能正常使用。SPM的安装方法见文matlab2021a版本条件下安装spm_kidllll的博客-优快云博客 1、下载安装包 下载地址:DPABI: a toolbox for Data Processing & Analysis for Brain Imaging | The R-fMRI Network 2、将下载好的dpabi文件夹移动到matl..

qq_42356925的博客 1万+

最小二乘法(看完即会)

其中,X是数据矩阵,每一行是一个数据点,每一列是一个自变量(包括截距项),Y是观测值向量,β是待求的系数向量。为了找到使S最小的a和b的值,我们需要对S求关于a和b的偏导数,并令它们等于零。最小二乘法的数学公式通常用于线性回归问题,其中目标是找到一条直线(或更高维度的超平面),使得这条直线与给定数据点的误差平方和最小。同样地,通过求偏导数和令偏导数等于零,我们可以得到一个线性方程组,解这个方程组可以找到最优的b_0, b_1, …+ b_m*x_m,其中b_0是截距,b_1到b_m是各个自变量的系数。

qlkaicx的博客 2万+

监听HttpSessionListener时不能使用依赖注入的解决方法

监听HttpSessionListener时不能使用依赖注入的解决方法 通过使用applicationContext来获取bean ApplicationContext applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext( httpSessionEvent.getSession().getServletContext()); applicationContext

weixin_42947972的博客 424

Playwright与MCP协议结合:AI驱动的智能Web自动化测试实践

Web自动化测试是现代软件开发流程中保障产品质量的关键环节,其核心原理是通过程序模拟用户操作,对Web应用进行功能验证。传统自动化测试工具如Selenium和Playwright虽然提供了强大的API,但脚本编写和维护仍需较高的编程技能。随着AI技术的发展,智能测试成为新的趋势,它通过自然语言理解和自动化执行,显著降低了测试创建门槛。Model Context Protocol(MCP)作为一种连接AI模型与外部工具的开放协议,为自动化测试带来了“智能大脑”。通过将MCP与Playwright结合,测试人员

aoe41606的博客 604

依赖注入(C#)

设计模式学习笔记一,依赖注入(Dependency Injection,简称DI)设计模式中,尤其是结构型模式很多时候解决的就是对象间的依赖关系,变依赖关系具体为依赖具象。平时开发中如果发现客户程序依赖某个(或某类)对象,我们常常会对它们进行一次抽象,形成抽象的抽象类、接口,这样客户程序就可以摆脱所依赖的具体类型。二,实现(C#)示例情景假设,现在程序需要一个获取不同时间格式的的当前时间。 我们定

bin的专栏 1万+

无人机飞控技术最详细解读

已剪辑自: https://zhuanlan.zhihu.com/p/64519280[导读]被称作是“飞行器的大脑”的飞控到底是什么?以前,搞无人机的十个人有八个是航空、气动、机械出身,更多考虑的是如何让飞机稳定飞起来、飞得更快、飞得更高。如今,随着芯片、人工智能、大数据技术的发展,无人机开始了智能化、终端化、集群化的趋势,大批自动化、机械电子、信息工程、微电子的专业人材投入到了无人机研发大潮中,几年的时间让无人机从远离人们视野的军事应用飞入了寻常百姓家、让门外汉可以短暂的学习也能稳定可靠的飞行娱乐。不可

qq_41854911的博客 1万+

网络可视化工具netron详细安装流程

netron安装目录1.netron 简介2.不同操作系统下的安装使用方式2.1 在线版本:只要有浏览器就可以2.2 不同操作系统安装使用3.netron支持的网络框架4.netron测试演示 1.netron 简介 在实际的项目中,经过会遇到各种网络模型,需要我们快速去了解网络结构。如果单纯的去看模型文件,脑海中很难直观的浮现网络的架构。 这时,就可以使用netron可视化工具,可以清晰的看到每一层的输入输出,网络总体的架构,而且支持各种不同网络框架,简单好用。 2.不同操作系统下的安装使用方式 2.1

江南研习社 12万+

spring四种依赖注入方式

平常的java开发中,程序员在某个类中需要依赖其它类的方法,通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理。 spring提出了依赖注入的思想,即依赖不由程序员控制,而是通过spring容器帮我们new指定实例并且将实例注入到需要该对象的类中。依赖注入的另一种说法是“控制反转”,通俗的理解是:平常我们new一个实例,这个实例的控制权是我们程序员,而控制反转...

zhaohong_bo的专栏 1万+

PMOS过压保护电路设计与仿真优化策略

本文深入探讨PMOS过压保护电路(OVP)的设计与仿真优化策略,详细解析PMOS管选型、稳压管特性及三极管配置等关键要素。通过Proteus仿真案例揭示典型设计误区,并提供响应速度提升、抗干扰设计等进阶优化方案,助力工程师实现高可靠性的电源保护系统设计。

weixin_42620340的博客 440

Spring 的依赖注入

文章目录一、依赖注入的概念二、构造函数注入三、set 方法注入(更常用的方式)四、注入集合属性 一、依赖注入的概念 依赖注入: Dependency Injection,它是 spring 框架核心 IOC 的具体实现,具体点就是依赖关系的维护称之为依赖注入 我们的程序在编写时, 通过控制反转, 把对象的创建交给了 spring,但是代码中不可能出现没有依赖的情况。 IOC 解耦只是降低他们的依赖关系,但不会消除。 例如:我们的业务层仍会调用持久层的方法。 那这种业务层和持久层的依赖关系, 在使用 spri

南淮北安的博客 6820

工业自动化实战:用LabVIEW的DSC模块实现MODBUS-TCP设备控制

本文详细介绍了如何利用LabVIEW的DSC模块实现工业自动化中的MODBUS-TCP设备控制。通过环境准备、核心功能解析、状态机实现及典型工业场景实战,帮助工程师快速掌握稳定可靠的通讯技术,提升工业自动化系统的运行效率。

salt9的博客 1057

《备考信息系统项目管理师》 - 专栏介绍和目录

本专栏会持续详细梳理软考高级信息系统项目管理师(高项)的考点、所有历年真题(包括综合知识、案例分析、论文)等,有论文专项,预测模拟题等内容。需要的可以先订阅下哦。

数据知道的博客 2万+

spring依赖注入三种方式

spring依赖注入

qishiheyongshi的专栏 1万+

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

【Spring】 - 基于xml的两种依赖注入方式(构造函数注入,setter注入)

概述 Spring中依赖注入dependency injection (DI)一般来说有两种形式: 1)基于xml的依赖注入, 2)基于注解的依赖注入。 基于xml的依赖注入方式通常又可以分为:1)构造函数方式注入。2)setter方式注入。 环境 Spring4.3.9, JDK1.8  pom添加spring依赖如下: org.springframewo

LightOfMiracle的博客 4821

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Spring的依赖注入 构造函数注入 Set注入

spring中的依赖注入 依赖注入: Dependency Injection IOC的作用: 降低程序间的耦合(依赖关系) 依赖关系的管理: 以后都交给spring来维护 在当前类需要用到其他类的对象,由spring为我们提供,我们只需要在配置文件中说明 依赖关系的维护 就称之为依赖注入。 依赖注入: 能注入的数据类型:有三类 基本类型和String 基本bea...

韦恩少爷的博客 1394

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Spring依赖注入的方式

本文主要介绍Spring的依赖注入,列举了几种依赖注入的方式,包括基于注解的注入、基于XML文件的注入,基于Aware接口回调的注入、基于Bean DefinitionAPI的注入、以及分组注入,对于这些依赖注入的方式分别通过代码示例展示了它们的用法。通过这篇文章的内容可以加深对Spring依赖注入的印象,同时在开发过程中能够更灵活的实现相关的功能。

qq_43408971的博客 1028

浅谈spring4泛型依赖注入

本文简单分析了Spring 4.0的新特性泛型依赖注入。本文以我自己编写的代码为例子,详细论述了泛型依赖注入的两种实现方式,同时讨论了泛型依赖注入的优点,部分原理,以及各种实现的优缺点。

新手程序猿的学习日记 1万+

Spring中的依赖注入(三种注入方式:构造函数注入、set方法注入、基于注解注入)

概述   依赖注入: 在当前类需要用到其他类的对象,由spring为我们提供,我们只需要在配置文件中说明依赖关系的维护   IoC的作用: 降低程序间的耦合(依赖关系) 注入方式 构造函数注入 使用的标签:constructor-arg 标签出现的位置:bean标签的内部 标签中的属性: 属性 属性值 type 根据数据的数据类型进行赋值(当有多个相同数据类型,不方便) index 根据构造函数中指定索引位置的参数赋值。索引的位置是从0开始(不知晓,某个索引的数据类型是什么) n

Eva_xiaoxi的博客 2212

Spring依赖注入有哪些方式?

有4中注入方式: 1.Set方法注入:注入最简单,最常用的注入方式,支持注解+xml。 2.构造器注入:是指带有参数的构造函数注入,支持注解+xml 3.静态工厂的方式注入:通过调用静态工厂的方法来获取自己需要的对象,只支持xml。 4.实例工厂的方式注入:获取对象实例的方法不是静态的,所以需要new一个工厂类,再调用普通的实例方法,只支持xml。 有两种实现方式: 1.注解(@Autowired,@Resource,@Required) 2.配置文件(xml) 简要回答 1.set注入,构造器注入,静态工

qq_46138725的博客 2524

Spring常用的三种依赖注入方式

日常开发中,某个类需要依赖其它类的方法,通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理; spring提出了依赖注入的思想,即依赖类不由程序员实例化,而是通过spring容器帮我们new指定实例,并且将实例注入到需要该对象的类中。 依赖注入的另一种说法是“控制反转”,通俗的理解是:平常我们new一个实例,这个实例的控制权是我们程序员,而控制反转是指ne...

Sucker的小笔记 4986

Spring 依赖注入详解

依赖注入(DI)是一种设计模式,允许开发者在创建对象时不必直接在代码中实例化依赖对象,而是将这些依赖关系的创建和维护交给容器来完成。Spring提供了多种方式来实现依赖注入,包括XML配置、注解和Java配置类。依赖注入是Spring框架中非常强大的一个特性,它不仅降低了对象之间的耦合度,还提高了代码的可维护性和可测试性。通过XML配置、注解和Java配置类,Spring提供了灵活多样的方式来实现依赖注入,使得开发者可以根据项目需求选择合适的实现方式。版权声明。

ning的博客 1461
上一篇: IntelliJ IDEA——快速搭建spring boot项目,IntelliJ IDEA快速搭建spring boot项目
下一篇: dom4j格式化(美化)生成(导出)的xml
Walter Sun
博客等级 码龄9年 1726粉丝 288原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Walter Sun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值