Spring官方真的不建议使用属性进行依赖注入吗?

news2024/11/26 22:52:51

使用Spring进行依赖注入时,很多大佬都推荐使用构造方法注入,而非使用在属性上添加 @Autowired 注入,而且还说这是Spring官方说的,真的是这样吗?

使用Spring进行依赖主要的方式有很多,主流的使用方式有两种:

  • 1.在属性或者setter方法上使用@Autowired进行注入

  • 2.在构造方法上使用@Autowired进行注入

那么哪种方式更好一点呢?

很巧,在看Spring文档的时候看到了这样一段描述:

在这里插入图片描述

可以参考:Dependency Injection

上面描述主要表达三个信息:

  • 1.两者可以混合使用,对于必须的依赖项,使用构造函数;而对于可选的依赖项,使用setter方法或属性依赖。

  • 2.如果依赖项是不可变的,建议使用构造器进行注入,但是构造器参数过多时,意味着类可能承担了过多的职责,代码就变的不好维护。

  • 3.对于一些三方框架,构造方法或者setter方法没有对外暴露,依赖注入的方式需要根据实际情况进行选择。

如果把以上三点总结成一点的话,就是:根据具体场景进行选择

既然是这样,那么为啥还有大佬一直强调:要使用构造器注入呢?难道大佬没有看文档吗?

我觉得应该是看过了上面的文档,然后才这样强调的,原因在于:

  • 1.为了方便管理和统一编码风格,有些公司会有自己特定的开发模式和规范。

  • 2.同时更加看重构造器注入的带来的好处。

那么使用构造器注入有哪些优点呢?

1.不变性

通过将依赖项设置为 final,我们确保了在对象创建之后,依赖项不能被修改。这提高了代码的可维护性和可预测性。

@Component
public class MyBean {
    private final Dependency1 dependency1;

    // 只有一个构造函数时,可以省略@Autowired
    public MyBean(Dependency1 dependency1) {
        this.dependency1 = dependency1;
    }
}  

2.更清晰的依赖

构造方法注入明确地指定了类所需的依赖项,因此理解代码需要哪些输入变得非常容易。


public class MyBean {
    private final Dependency1 dependency1;
    private final Dependency2 dependency2;

    public MyBean(Dependency1 dependency1, Dependency2 dependency2) {
        this.dependency1 = dependency1;
        this.dependency2 = dependency2;
    }
}

3.可测试性

构造方法注入简化了测试过程,因为我们可以在创建类的实例时很容易地使用 mock 对象替代真实依赖。

public class MyBeanTest {
    @Test
    public void testMyBean() {
        Dependency1 mockDependency1 = Mockito.mock(Dependency1.class);
        Dependency2 mockDependency2 = Mockito.mock(Dependency2.class);

        MyBean myBean = new MyBean(mockDependency1, mockDependency2);

        // ...编写测试用例...
    }
}

4.更容易发现错误

构造方法注入确保必需的依赖在对象创建时就满足,这有助于发现问题并在应用启动期间捕获错误。

public class MyBean {
    private final Dependency1 dependency1;

    public MyBean(Dependency1 dependency1) {
        if(dependency1 == null) {
            throw new IllegalArgumentException("Dependency1 cannot be null");
        }
        this.dependency1 = dependency1;
    }
}

在使用构造器注入的过程中,如果依赖项不断变化,那么每次变化,构造器方法签名就需要不断修改,比较麻烦,这里推荐大家使用一个插件:Lombok

如果你的项目使用了 Lombok 的话,可以使用 @AllArgsConstructor 注解自动生成包含所有成员变量的构造方法。

这样,在添加新的属性时,就不再需要显式地修改构造方法。

import lombok.AllArgsConstructor;

@AllArgsConstructor
public class MyBean {
    private final Dependency1 dependency1;
    private final Dependency2 dependency2;
}

对 Lombok 不熟悉的老铁可以参考:lombok使用与原理介绍

今日分享如果对你有帮助,帮忙点个关注

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

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

相关文章

kaggle竞赛(房价预测)(Pytorch 06)

一 下载数据集 此数据集由Bart de Cock于2011年收集,涵盖了2006‐2010年期间 亚利桑那州 埃姆斯市的房价。 下载地址: import hashlib import os import tarfile import zipfile import requests#save DATA_HUB dict() DATA_URL http://d2l-data.s3…

linux在使用重定向写入文件时(使用标准C库函数时)使处理信号异常(延时)--问题分析

linux在使用重定向写入文件时(使用标准C库函数时)使处理信号异常(延时)–问题分析 在使用alarm函数进行序号处理测试的时候发现如果把输出重定向到文件里面会导致信号的处理出现严重的延迟(ubuntu18) #include <stdio.h> #include <stdlib.h> #include <unist…

Java23种常见设计模式汇总

七大原则网站地址&#xff1a;设计模式7大原则&#xff0b;类图关系-CSDN博客 创建型设计模式&#xff1a;创建型设计模式合集-CSDN博客 七大结构型设计模式&#xff1a;7大结构型设计模式-CSDN博客 11种行为型设计模式&#xff1a; 11种行为型模式&#xff08;上&#xff0…

LeetCode---390周赛

题目列表 3090. 每个字符最多出现两次的最长子字符串 3091. 执行操作使数据元素之和大于等于 K 3092. 最高频率的 ID 3093. 最长公共后缀查询 一、每个字符最多出现两次的最长子字符串 非常经典的滑动窗口问题&#xff0c;即动态维护一段区间&#xff0c;使得这段区间满足…

数据结构:Trie(前缀树/字典树)

文章目录 一、介绍Trie1.1、Trie的结点结构1.2、Trie的整体结构 二、Trie的操作2.1、Trie插入操作2.2、Trie查找操作2.3、Trie前缀匹配操作2.4、Trie删除操作 三、实战3.1、实现Trie&#xff08;前缀树&#xff09; 一、介绍Trie Trie 又称字典树、前缀树和单词查找树&#xff…

短视频素材那里来?五大平台让你的视频大放异彩!

哈喽&#xff01;短视频创作者们&#xff0c;是不是在寻找那些能让你的剪辑视频更加闪耀的素材&#xff1f;别着急&#xff0c;今天我要为你们带来五个超棒的视频素材网站&#xff0c;让你的作品在抖音、快手上大放异彩&#xff0c;成为众人羡慕的焦点&#xff01; 蛙学网&…

python电商结合双轨制

最近又重新整合翻看以前的数据&#xff0c;图片&#xff0c;绘画&#xff0c;还有各种编程代码&#xff0c;python,leetcode,还有关于商业方面的一些见解,想起了大学时候和同学们并肩作战&#xff0c;熬夜编码的时光。还有大数据&#xff0c;八爪鱼爬虫。 下面是我的手稿电商打…

输出单链表倒数第K个结点值

方法一&#xff1a; 两次遍历链表。第一次遍历&#xff0c;计算链表长度&#xff0c;然后计算链表倒数第m个结点的正数位置k&#xff0c;判断位置是否合法&#xff0c;如果不合法&#xff0c;输出NOT FOUND&#xff0c;否则&#xff0c;进行第二次遍历链表&#xff0c;查找链表…

【初阶数据结构】——牛客:CM11 链表分割

文章目录 1. 题目介绍2. 思路分析3. 代码实现 1. 题目介绍 链接: link 这道题是给我们一个链表和一个值X &#xff0c;要求我们以给定值x为基准将链表分割成两部分&#xff0c;所有小于x的结点排在大于或等于x的结点之前。 最终返回重新排列之后的链表的头指针。 2. 思路分析…

根据实例逐行分析NIO到底在做什么

Selector&#xff08;选择器&#xff09;是 Channel 的多路复用器&#xff0c;它可以同时监控多个 Channel 的 IO 状况&#xff0c;允许单个线程来操作多个 Channel。Channel在从Buffer中获取数据。 选择器、通道、缓冲池是NIO的核心组件。 一、新建选择器 此时选择器内只包含…

Python学习笔记-简单案例实现多进程与多线程

Python 的多进程与多线程是并发编程的两种重要方式&#xff0c;用于提高程序的执行效率。它们各自有不同的特点和适用场景。 多进程&#xff08;Multiprocessing&#xff09; 概念&#xff1a; 多进程是指操作系统中同时运行多个程序实例&#xff0c;每个实例称为一个进程。…

FA模型切换Stage模型组件切换之ServiceAbility切换DataAbility切换

ServiceAbility切换 FA模型中的ServiceAbility对应Stage模型中的ServiceExtensionAbility。Stage模型下的ServiceExtensionAbility为系统API&#xff0c;只有系统应用才可以创建。因此&#xff0c;FA模型的ServiceAbility的切换&#xff0c;对于系统应用和三方应用策略有所不同…

Java线程池工作原理浅析

为什么要用线程池&#xff1f; 1、线程属于稀缺资源&#xff0c;它的创建会消耗大量系统资源 2、线程频繁地销毁&#xff0c;会频繁地触发GC机制&#xff0c;使系统性能降低 3、多线程并发执行缺乏统一的管理与监控 线程池的使用 线程池的创建使用可通过Executors类来完成…

Clip算法解读

论文地址&#xff1a;https://arxiv.org/pdf/2103.00020.pdf 代码地址&#xff1a;https://github.com/OpenAI/CLIPz 中文clip代码&#xff1a;https://gitcode.com/OFA-Sys/Chinese-CLIP/overview 一、动机 主要解决的问题&#xff1a; 超大规模的文本集合训练出的 NLP 模…

vue属性与方法

vue属性与方法 计算属性v-model指令——表单的实现样式绑定 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"&g…

前端面试拼图-数据结构与算法(二)

摘要&#xff1a;最近&#xff0c;看了下慕课2周刷完n道面试题&#xff0c;记录下... 1. 求一个二叉搜索树的第k小值 二叉树(Binary Tree) 是一棵树 每个节点最多两个子节点 树节点的数据结构{value, left?, right?} 二叉树的遍历 前序遍历&#xff1a;root→left→right 中…

Java类与对象:从概念到实践的全景解析!

​ 个人主页&#xff1a;秋风起&#xff0c;再归来~ 文章专栏&#xff1a;javaSE的修炼之路 个人格言&#xff1a;悟已往之不谏&#xff0c;知来者犹可追 克心守己&#xff0c;律己则安&#xff01; 1、类的定义格式 在java中定义类时需要用到…

记录一个写自定义Flume拦截器遇到的错误

先说结论&#xff1a; 【结论1】配置文件中包名要写正确 vim flume1.conf ... a1.sources.r1.interceptors.i1.type com.atguigu.flume.interceptor.MyInterceptor2$MyBuilder ... 标红的是包名&#xff0c;表黄的是类名&#xff0c;标蓝的是自己加的内部类名。这三个都…

大话设计模式之工厂模式

工厂模式&#xff08;Factory Pattern&#xff09;是一种创建型设计模式&#xff0c;它提供了一种创建对象的最佳方式&#xff0c;而无需指定将要创建的对象的确切类。通过使用工厂模式&#xff0c;我们可以将对象的创建和使用分离&#xff0c;从而使代码更具灵活性和可维护性。…

Python之Opencv教程(1):读取图片、图片灰度处理

1、Opencv简介 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个用于计算机视觉和图像处理的开源库&#xff0c;提供了丰富的图像处理、计算机视觉和机器学习功能。它支持多种编程语言&#xff0c;包括C、Python、Java等&#xff0c;广泛应用于图像处…