当前位置: 首页 > news >正文

Spring DI 笔记

目录

1.什么是DI?

 2.依赖注入的三种⽅式

2.1属性注⼊ 

2.2构造⽅法注⼊

 2.3Setter 注⼊

 2.4三种注⼊优缺点分析

3.@Autowired存在问题 


1.什么是DI?

DI: 依赖注⼊
依赖注⼊是⼀个过程,是指IoC容器在创建Bean时, 去提供运⾏时所依赖的资源,⽽资源指的就是对象

简单来说, 就是把对象取出来放到某个类的属性中.

关于依赖注⼊, Spring也给我们提供了三种⽅式:

1.属性注⼊(Field Injection)

2.构造⽅法注⼊(Constructor Injection)

3.Setter 注⼊(Setter Injection)

都是使用@Autowired实现的。 

接下来,我们分别来看.


 2.依赖注入的三种⽅式

都是使用@Autowired实现的 

我们接下来会频繁使用到UserService类和UserController类以及获取 UserController 中的 sayHi⽅法。

1.UserService代码:

import org.springframework.stereotype.Service;@Service
public class UserService {public void doService(){System.out.println("doService~~~~");}
}

 2.UserController类依照我们选择的注入⽅式决定。

3.获取 UserController 中的 sayHi⽅法:

​
import com.wh.ioc.Controller.UserController;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;//@ComponentScan(basePackages = "~~~~~")
@SpringBootApplication
public class SpringIocApplication {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(SpringIocApplication.class, args);UserController bean = context.getBean(UserController.class);bean.sayHi();}
}​

2.1属性注⼊ 

UserController类的实现代码如下:

import com.wh.ioc.Service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController {@Autowiredprivate UserService userService;public void sayHi(){userService.doService();System.out.println("UserController Hi");}
}

2.2构造⽅法注⼊

import com.wh.ioc.Service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController {private UserService userService;public UserController() {}@Autowiredpublic UserController(UserService userService) {this.userService = userService;}public void sayHi(){userService.doService();System.out.println("UserController Hi");}
}

注意:

  如果类只有⼀个构造⽅法,那么 @Autowired 注解可以省略;如果类中有多个构造⽅法,
那么需要添加上 @Autowired 来明确指定到底使⽤哪个构造⽅法。

 补充:

关于构造函数规范:

1.当我们添加有参构造函数时,一定也要把无参构造函数也添加上。

2.依赖注入时,就算只有一个构造函数也要添加@Autowired注解

 2.3Setter 注⼊

注解一定不能少

import com.wh.ioc.Service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController {private UserService userService;@Autowiredpublic void setUserService(UserService userService) {this.userService = userService;}public void sayHi(){userService.doService();System.out.println("UserController Hi");}
}

 2.4三种注⼊优缺点分析

1.属性注⼊

优点:

简洁,使⽤⽅便

缺点:

(1) 只能⽤于 IoC 容器 ,如果是⾮ IoC 容器不可⽤,并且只有在使⽤的时候才会出现 NPE(空指 针异常)
(2) 不能注⼊⼀个Final修饰的属性

 2.构造函数注⼊(Spring 4.X推荐)

 优点:

(1)注⼊的对象不会被修改

(2)可以注⼊final修饰的属性

(3)依赖对象在使⽤前⼀定会被完全初始化,因为依赖是在类的构造⽅法中执⾏的,⽽构造⽅法 是在类加载阶段就会执⾏的⽅法

(4)通⽤性好, 构造⽅法是JDK⽀持的, 所以更换任何框架,他都是适⽤的

缺点:

注⼊多个对象时, 代码会⽐较繁琐 

3.Setter注⼊(Spring 3.X推荐)  

优点:
⽅便在类实例之后, 重新对该对象进⾏配置或者注⼊

缺点:

1.不能注⼊⼀个Final修饰的属性

2.注⼊对象可能会被改变, 因为setter⽅法可能会被多次调⽤, 就有被修改的⻛险 


3.@Autowired存在问题 

我们接下来用打印学生信息的例子来说明

Student类:

import lombok.Data;@Data
public class Student {private String name;private Integer id;public Student() {}public Student(String name) {this.name = name;}public Student(String name, Integer id) {this.name = name;this.id = id;}
}
BeanConfig类:
import com.wh.ioc.Model.Student;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class BeanConfig {@Beanpublic Student StudentInfo() {return new Student("wh",01);}@Beanpublic Student StudentInfo2() {return new Student("Bob",02);}
}
DomeController类:
import com.wh.ioc.Model.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class DomeController {@Autowiredprivate Student student;public void say(){System.out.println(student);}
}

启动类:

import com.wh.ioc.Controller.DomeController;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;//@ComponentScan(basePackages = "~~~~~")
@SpringBootApplication
public class SpringIocApplication {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(SpringIocApplication.class, args);DomeController bean = context.getBean(DomeController.class);bean.say();}
}

运行:

报错的原因是,⾮唯⼀的 Bean 对象 

解释:

@Autowired是先按照类型去注入,匹配到多个对象时,再按照名称去注入。

如果我们明确注入对象的名称,则可以正确打印该学生信息。

DomeController类代码:

import com.wh.ioc.Model.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class DomeController {@Autowiredprivate Student StudentInfo2;public void say(){System.out.println(StudentInfo2);}
}

结果:

 

那当我们没有明确注入对象的名称,又想得到正确结果我们可以怎么做?

有以下⼏种解决⽅案:
1.@Primary
2.@Qualifier
3.@Resource

1. @Primary

使⽤@Primary注解:当存在多个相同类型的Bean注⼊时,加上@Primary注解,来确定默认的实现。

直接加到Bean注⼊的方法上。

@Primary
@Bean
public Student StudentInfo() {return new Student("wh", 01);
}

2.@Qualifier

使⽤@Qualifier注解:指定当前要注⼊的bean对象。 在@Qualifier的value属性中,指定注⼊的bean 的名称。
@Qualifier注解不能单独使⽤,必须配合@Autowired使⽤
@Controller
public class DomeController {@Qualifier("StudentInfo2")@Autowiredprivate Student student;public void say(){System.out.println(student);}
}

3.@Resource注解

本身就是依赖注入注解,是按照bean的名称进⾏注⼊

@Controller
public class DomeController {@Resource(name = "StudentInfo")private Student student;public void say(){System.out.println(student);}
}

@Autowird 与 @Resource的区别是?

 1.@Autowired 是spring框架提供的注解,⽽@Resource是JDK提供的注解

 2.@Autowired 默认是按照类型注⼊,⽽@Resource是按照名称注⼊. 相⽐于 @Autowired 来说, @Resource ⽀持更多的参数设置,例如 name 设置,根据名称获取 Bean


以上为我个人的小分享,如有问题,欢迎讨论!!! 

都看到这了,不如关注一下,给个免费的赞 

 

相关文章:

Spring DI 笔记

目录 1.什么是DI? 2.依赖注入的三种⽅式 2.1属性注⼊ 2.2构造⽅法注⼊ 2.3Setter 注⼊ 2.4三种注⼊优缺点分析 3.Autowired存在问题 1.什么是DI? DI: 依赖注⼊ 依赖注⼊是⼀个过程,是指IoC容器在创建Bean时, 去提供运⾏时所依赖的资源,⽽资源指的…...

psutil库的使用说明

前言 psutil是一个跨平台的库,用于获取系统的进程和系统利用率(包括 CPU、内存、磁盘、网络等)信息。 目录 安装 应用场景 常用方法 一、系统信息相关函数 二、进程信息相关函数 三、网络信息相关函数 四、其他实用函数 使用样例 监控应…...

PMP--三模--解题--71-80

文章目录 7.成本管理--S曲线--S曲线对累计值进行监督和报告--S曲线可以同时报告成本与进度情况。适用于预测和敏捷项目。14.敏捷--信息发射源--是一种可见的实物展示其向组织内其他成员提供信息在不干扰团队的情况下即时实现知识共享。71、 [单选] 项目经理正在为刚刚进入第三次…...

iTextPDF 一个功能强大的 Java PDF 库

iTextPDF 是一个功能强大的 Java PDF 库,它提供了丰富的 API 用于创建和操作 PDF 文档。以下是一些 iTextPDF 的常用功能: 创建 PDF 文档:可以创建新的 PDF 文档,并设置页面大小、边距、背景颜色等 。 添加文本:在 PD…...

QT C++ 自学积累 『非技术文』

QT C 自学积累 『非技术文』 最近一段时间参与了一个 QT 项目的开发,使用的是 C 语法,很遗憾的是我之前从来没有接触过 C ,大学没有开过这堂课,也没用自己学习过,所有说上手贼慢,到现在为止其实也不是很清楚…...

浅谈虚拟内存(操作系统、Redis)

浅谈虚拟内存(操作系统、Redis) 参考&鸣谢 4.1 为什么要有虚拟内存? xiaolincoding 【简单说下】REDIS的虚拟内存机制,会吗?别翻书 aristo_boyunv Redis 虚拟内存 Java杨永杰 浅谈虚拟内存:操作系统与 Redis 在计算机系统中…...

【LeetCode HOT 100】详细题解之链表篇

LeetCode HOT 100题解之链表篇 160 相交链表题目分析代码 206 反转链表方法一:迭代 234 回文链表方法一:将值复制到数组中方法二:快慢指针 141 环形链表方法一:哈希表方法二:快慢指针 142 环形链表II方法一&#xff1a…...

二叉树的递归遍历

方法论 确定递归函数的参数和返回值 确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。 确定终止条件 写完了递归算法, 运行的时候,经常会遇到栈溢…...

国内访问OpenAI API

最近在学习LLM。绕不过去的肯定要学习OpenAI。 国内想直接使用官方API十分麻烦。就到处查资料及网友的分享。发现了这个代理可以在国内很方便的使用OpenAI API。 代理的地址如下: https://referer.shadowai.xyz/r/1014150 经过一段实际体验下来,这个…...

深入 Spring RestTemplate 源码:掌握 HTTP 通信核心技术

在上一篇文章《Spring Boot 项目高效 HTTP 通信:常用客户端大比拼!》里,我们提到了RestTemplate,它是Spring框架提供的Http客户端,在springboot项目开发过程中,属于使用最为广泛的 HTTP 客户端之一了。今天…...

计算机网络:计算机网络概述 —— 初识计算机网络

文章目录 计算机网络组成部分网络架构协议与标准网络设备网络类型作用实际应用案例 计算机网络 计算机网络是指将多台计算机通过通信设备和通信链路连接起来,以实现数据和信息的交换和共享的技术和系统。它是现代信息社会的基础设施之一,也是互联网的基…...

set和map结构的使用

个人主页:敲上瘾-CSDN博客 个人专栏:游戏、数据结构、c语言基础、c学习、算法 目录 一、序列式容器和关联式容器 二、set和multiset 1.insert 2.erase 3.find 4.count 三、map和mapmulti 1.pair 2.insert 3.find 4.operator[ ] 5.erase 6.lo…...

2. qt_c++反射实例

目录 使用场景元对象相关类及宏常用功能获取类相关内容以及委托调用 使用场景 Qt基于强大的元对象系统实现反射机制; 在复杂的开发需求中,我们希望通过一些手段映射出我们的类(映射对象) 然后直接使用,通过&#xff0…...

卷积神经网络(CNN)的计算量和参数怎么准确估计?

🍉 CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 1. 卷积层(Convolutional Layer) a) 计算量估计: 卷积层的 FLOPs 2 * H_out * W_out * C_in * C_out * K_h * K_w 详细解释: H_out, W_out&#xff…...

Ruby基础语法

Ruby 是一种动态、反射和面向对象的编程语言,它以其简洁的语法和强大的功能而受到许多开发者的喜爱。以下是 Ruby 语言的一些基本语法: 1. 打印输出 puts "Hello, Ruby!" 变量赋值 x 10 name "John" 2. 数据类型 Ruby 有多种…...

插入排序C++

题目: 样例解释: 【样例解释 #1】 在修改操作之前,假设 H 老师进行了一次插入排序,则原序列的三个元素在排序结束后所处的位置分别是 3,2,1。 在修改操作之后,假设 H 老师进行了一次插入排序,则原序列的三个…...

修改ID不能用关键字作为ID校验器-elementPlus

1、校验器方法 - forbiddenCharValidator const idUpdateFormRef ref(null); const forbiddenCharValidator (rule, value, callback) > {const forbiddenCharacters [as,for,default,in,join,left,inner,right,where,when,case,select];for (let forbiddenCharacter o…...

一文详解WebRTC、RTSP、RTMP、SRT

背景 好多开发者,希望对WebRTC、RTSP、RTMP、SRT有个初步的了解,知道什么场景该做怎样的方案选择,本文就四者区别做个大概的介绍。 WebRTC 提到WebRTC,相信好多开发者第一件事想到的就是低延迟,WebRTC(W…...

全国职业院校技能大赛(大数据赛项)-平台搭建Zookeeper笔记

ZooKeeper是一个分布式的、开放源码的分布式应用程序协调服务,为分布式应用提供一致性服务。它的设计目标是简化分布式系统的管理,保证多个节点之间的数据一致性和协调工作。ZooKeeper提供了类似文件系统的层次化命名空间,用来存储和管理元数…...

不同领域神经网络一般选择什么模型作为baseline(基准模型)

在神经网络研究中,选择合适的baseline(基线模型)是评估新方法有效性的重要步骤。基线模型通常是领域内公认的、性能良好的参考模型,用于比较和验证新提出模型的优势。以下是一些在不同任务和领域中常见的基线模型选择:…...

华为-IPv6与IPv4网络互通的6to4自动隧道配置实验

IPv4向IPv6的过渡不是一次性的,而是逐步地分层次地。在过渡时期,为了保证IPv4和IPv6能够共存、互通,人们发明了一些IPv4/IPv6的互通技术。 本实验以6to4技术为例,阐述如何配置IPv6过渡技术。 配置参考 R1 # sysname R1 # ipv6# interface GigabitEthernet0/0/1ip address 200…...

【spring中event】事件简单使用

定义事件类 /* * 1. 定义事件类 * 首先,我们创建一个自定义事件 UserRegisteredEvent,用于表示用户注册事件。 * */ public class UserRegisteredEvent extends ApplicationEvent {private final String email;public UserRegisteredEvent(Object sourc…...

leetcode每日一题day19(24.9.29)——买票需要的时间

思路:在最开始的情况下每人需要买的票数减一是能保持相对位置不变的, 如果再想减一就有可能 有某些人只买一张票,而离开了队伍, 所有容易想到对于某个人如果比当前的人买的多就按当前的人数量算 因为在一次次减一的情况下&#xf…...

智源研究院推出全球首个中文大模型辩论平台FlagEval Debate

近日,智源研究院推出全球首个中文大模型辩论平台FlagEval Debate,旨在通过引入模型辩论这一竞争机制对大语言模型能力评估提供新的度量标尺。该平台是智源模型对战评测服务FlagEval大模型角斗场的延展,将有助于甄别大语言模型的能力差异。 F…...

python实用脚本(二):删除xml标签下的指定类别

介绍 在目标检测中,有些时候会遇到标注好的类别不想要了的情况,这时我们可以运行下面的代码来批量删除不需要的类别节省时间。 代码实现: import argparseimport xml.etree.ElementTree as ET import osclasses [thin_smoke]def GetImgNam…...

vue3 父子组件调用

vue3 父子组件调用 父组件调用子组件方法 子组件使用defineExpose将方法抛出 父组件定义 function&#xff0c;子组件通过 defineExpose 暴露方法&#xff0c;父组件通过 ref 获取子组件实例&#xff0c;然后通过 ref 获取子组件方法。 // 父组件 <template><div>…...

线性模型到神经网络

&#x1f680; 在初始神经网络那一节&#xff08;链接如下&#xff1a;初始神经网络&#xff09;的最后&#xff0c;我们通过加大考虑的天数使得我们最后得到的模型Loss最终停留在了0.32k&#xff0c;当我们在想让模型更加准确的时候&#xff0c;是做不到的&#xff0c;因为我们…...

【架构】前台、中台、后台

文章目录 前台、中台、后台1. 前台&#xff08;Frontend&#xff09;特点&#xff1a;技术栈&#xff1a; 2. 中台&#xff08;Middleware&#xff09;特点&#xff1a;技术栈&#xff1a; 3. 后台&#xff08;Backend&#xff09;特点&#xff1a;技术栈&#xff1a; 示例场景…...

Stable Diffusion 蒙版:填充、原图、潜空间噪声(潜变量噪声)、潜空间数值零(潜变量数值零)

在Stable Diffusion中&#xff0c;蒙版是一个重要工具&#xff0c;它允许用户对图像的特定部分进行编辑或重绘。关于蒙版蒙住的内容处理选项&#xff0c;包括填充、原图、潜空间噪声&#xff08;潜变量噪声&#xff09;、浅空间数值零&#xff08;潜变量数值零&#xff09;&…...

ffmpeg录制视频功能

本文目录 1.环境配置2.ffmpeg编解码的主要逻辑&#xff1a;3. 捕获屏幕帧与写入输出文件4. 释放资源 在录制结束时&#xff0c;释放所有分配的资源。5.自定义I/O上下文6.对于ACC编码器注意事项 1.环境配置 下载并安装FFmpeg库 在Windows上 从FFmpeg官方网站下载预编译的FFmpeg…...

现在在市场上做网站怎么样/百度关键词挖掘查排名工具

CSS美化INPUT placeholder效果。CSS代码美化文本框里的placeholder文字。 ::selection伪元素 简而言之&#xff1a;单冒号(:)用于CSS3伪类&#xff0c;双冒号(::)用于CSS3伪元素。 伪元素由双冒号和伪元素名称组成。双冒号是在当前规范中引入的&#xff0c;用于区分伪类和伪元素…...

网站建设客户告知书/推广普通话内容100字

test voice port 0/0/1 relay ring on 测试线路 csim start 1002 隐藏命令&#xff0c;用来测试路由 show voice port summary 查看端口 show dial-peer voice summary 查看路由 传统pots精准号码会被吃号 no digit-strip forward-digits all prefix 1001 配置T302需要在连…...

华为网站建站/网上代写文章一般多少钱

之前编译的参数没有添加mysqli支持&#xff0c;因代码需要&#xff0c;必须添加上去。这次尝试一下扩展编译。 由于是源代码安装的&#xff0c;所以在php的目录bin下面有相关的命令。 到解压的源代码的ext目录下面&#xff0c;进入mysqli目录&#xff0c;执行/home/php/bin/php…...

相亲网站策划书/宁德市教育局官网

目录 Apache Nginx Tomcat Web日志的分析 在很多时候&#xff0c;我们经常需要分析网站的日志&#xff0c;以此来查看网站运行的各种情况。比如说如果网站被攻击&#xff0c;我们可以通过查看日志来溯源攻击者。 Apache 日志目录&#xff1a;/Apache/logs/ logs目录下有两…...

mip 网站/关键词整站优化

本文转自&#xff1a;https://www.imooc.com/article/17290 上节回顾 上篇记录了我对MySQL 事务 隔离级别read uncommitted的理解。 这篇记录我对 MySQL 事务隔离级别 read committed & MVCC 的理解。 前言 可以很负责人的跟大家说&#xff0c;MySQL 中的此隔离级别不单单…...

wordpress 自动邮件/2022最近十大的新闻热点

一、多进程 1.主进程和子进程 多任务处理&#xff1a;使得计算机可以同时处理多个任务听歌的同时QQ聊天、办公、下载文件 程序执行就是一个进程 主程序&#xff08;就是主进程&#xff09;中可以包含很多的其他进程。在主进程中添加了子进程&#xff0c;这样每个子进程可以在不…...