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

理解Spring中的依赖注入和控制反转

依赖注入(Dependency Injection)是一种面向对象编程的设计模式,用于解决对象之间的依赖关系。它的基本思想是将对象的创建和管理工作交给容器来完成,而不是在应用程序中手动创建和管理对象,从而达到松耦合、易维护、易测试的目的。依赖注入的实现原理是通过反射机制实现的。当一个对象需要依赖其他对象时,容器会通过反射机制查找和创建相应的对象,并将它们注入到需要依赖的对象中。这样,对象之间的依赖关系就由容器来维护,开发者只需要通过配置文件或注解等方式,告诉容器如何创建和注入对象。

在 Spring 框架中,依赖注入是通过 IoC(Inverse of Control,控制反转)实现的。IoC 容器在启动时,会扫描应用程序中的 Bean,并为每个 Bean 创建一个实例,并将它们存储在容器中。当其他 Bean 需要依赖这些 Bean 时,容器会自动将它们注入到需要依赖的 Bean 中。

具体来说,Spring 框架中的依赖注入主要有以下三种方式:

  1. 基于构造函数的依赖注入:通过构造函数来注入依赖项。

  1. 基于 Setter 方法的依赖注入:通过 Setter 方法来注入依赖项。

  1. 基于字段注入:通过直接将依赖项注入到类的字段中来实现。

那么什么是控制反转IoC呢?IoC 的基本思想是将程序中对象之间的依赖关系由程序员手动控制转变为由容器自动控制,即将对象的创建和管理工作交给容器来完成,而不是在应用程序中手动创建和管理对象。

依赖注入实际是通过反射机制实现的,反射机制实现依赖注入的具体步骤如下所示:

  1. 读取配置文件或者注解,获取依赖关系信息。

  1. 遍历依赖关系,通过反射机制获取依赖对象的类类型,然后使用 Class 类的 newInstance() 方法创建对象实例。

  1. 如果依赖对象有构造器参数,则通过递归调用实现构造器注入。

  1. 如果依赖对象有 setter 方法,则通过反射调用 setter 方法实现属性注入

既然依赖注入本质是通过反射机制实现,那么什么是反射机制呢?反射机制是指在程序运行时动态获取类信息、访问或修改对象属性、调用对象方法等操作的一种机制。Java 反射机制提供了一组 API,使得程序能够在运行时获取并使用类的信息,而不需要在编译期间就确定。Java 反射机制提供了以下一些常用的 API:

  1. Class 类:表示一个类的信息,可以获取类名、包名、父类、接口、构造器、属性、方法等信息。

  1. Constructor 类:表示一个类的构造器信息,可以获取构造器的参数、修饰符、注解等信息。

  1. Field 类:表示一个类的属性信息,可以获取属性名、类型、修饰符、注解等信息。

  1. Method 类:表示一个类的方法信息,可以获取方法名、返回类型、参数、修饰符、注解等信息。

  1. Modifier 类:提供了一组静态方法,可以判断一个类、方法或属性的修饰符,如 public、private、static、final 等。

  1. Array 类:提供了一组静态方法,可以创建数组对象、获取数组长度、获取数组元素等信息。

下面是一段demo代码,通过实际代码来理解Java提供的反射机制的API如何使用。如下图所示,左边是定义的一个简单Person的class,右边是调用反射机制提供的API或者Person类的构造器,属性,对属性进行设置,调用Person类的方法等。在获取属性时,我们使用了 setAccessible(true) 方法,这是因为 name 和 age 属性都是私有的,需要通过反射机制打开访问权限才能修改它们的值。在调用方法时,我们使用了 invoke 方法来执行该方法。

可以看到通过反射机制,可以获取构造函数,设置属性值等,下面看看如何通过反射机制提供的API实现依赖注入。在下面的代码中,创建了UserService,UserService依赖UserDao。使用Class.forName()方法获取UserService类的Class对象,然后使用getConstructor()方法获取UserService类的构造函数,该构造函数需要一个UserDao类型的参数。接着,我们创建一个UserDao对象,然后通过newInstance()方法调用构造函数来创建UserService对象并注入依赖。另外,我们还可以使用getMethod()方法获取UserService类的setter方法,然后使用invoke()方法调用该方法来注入依赖。

public class UserService {private UserDao userDao;// 构造函数注入public UserService(UserDao userDao) {this.userDao = userDao;}// setter方法注入public void setUserDao(UserDao userDao) {this.userDao = userDao;}
}
public class UserDao {// ...
}
public class Main {public static void main(String[] args) throws Exception {// 通过反射机制创建UserService对象并注入依赖Class<?> userServiceClass = Class.forName("com.example.UserService");Constructor<?> userServiceConstructor = userServiceClass.getConstructor(UserDao.class);UserDao userDao = new UserDao();UserService userService = (UserService) userServiceConstructor.newInstance(userDao);// 或者通过setter方法注入依赖Method setUserDaoMethod = userServiceClass.getMethod("setUserDao", UserDao.class);userDao = new UserDao();setUserDaoMethod.invoke(userService, userDao);}
}

以上是Spring使用Java的反射机制实现依赖注入的简单介绍。当然,Spring中的依赖注入还涉及到很多细节和实现方式,但是基本的原理就是通过反射机制动态地创建对象并注入依赖。总结而言,Spring实现依赖注入可以划分为4个步骤:

  1. 配置Bean

在Spring中,Bean的配置可以通过XML配置文件、注解或Java代码来实现。在配置中可以定义Bean的属性、依赖关系等信息,这部分是程序员编写,例如通过注解@Autowired等进行配置。

  1. 容器创建Bean

当Spring容器(容器是Spring框架的核心,它负责创建、管理和调用Bean)启动时,它会根据配置文件中的定义,通过Java的反射机制创建所有需要的Bean,并将它们存储在容器中。

  1. 注入依赖

在容器创建Bean的过程中,Spring会通过依赖注入的方式自动将Bean所需要的依赖注入到Bean中。这个过程可以通过构造器注入、setter注入或接口注入来实现。

  • 构造器注入:使用Bean的构造器来注入依赖。在Bean的构造器中,我们可以通过参数来传递依赖对象。Spring会通过Java的反射机制,自动为构造器注入需要的依赖对象。

  • setter注入:使用Bean的setter方法来注入依赖。在Bean中,我们可以定义setter方法来设置依赖对象。Spring会通过Java的反射机制,自动调用Bean的setter方法,将需要的依赖对象注入到Bean中。

  • 接口注入:使用接口来注入依赖。在Bean中,我们可以定义一个接口,并在接口中定义依赖注入的方法。Spring会通过Java的反射机制,自动实现这个接口,并将实现后的对象注入到Bean中。

总的来说,Spring实现依赖注入的核心就是将Bean的创建和依赖注入的过程交给了Spring容器来管理。Spring容器在创建Bean的过程中,通过Java的反射机制来自动完成Bean的依赖注入。这种方式可以大大减少代码的复杂度,提高代码的可读性和可维护性。

相关文章:

理解Spring中的依赖注入和控制反转

依赖注入&#xff08;Dependency Injection&#xff09;是一种面向对象编程的设计模式&#xff0c;用于解决对象之间的依赖关系。它的基本思想是将对象的创建和管理工作交给容器来完成&#xff0c;而不是在应用程序中手动创建和管理对象&#xff0c;从而达到松耦合、易维护、易…...

XXL-JOB

XXL-JOB介绍 XXL-JOB是一个轻量级分布式任务调度平台&#xff0c;其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线&#xff0c;开箱即用。 官网&#xff1a;https://www.xuxueli.com/xxl-job/ 文档&#xff1a;分布式任务调度…...

「牛客网C」初学者入门训练BC134,​BC136​

&#x1f436;博主主页&#xff1a;ᰔᩚ. 一怀明月ꦿ ❤️‍&#x1f525;专栏系列&#xff1a;线性代数&#xff0c;C初学者入门训练 &#x1f525;座右铭&#xff1a;“不要等到什么都没有了&#xff0c;才下定决心去做” &#x1f680;&#x1f680;&#x1f680;大家觉不错…...

华为OD机试题【翻转单词顺序】用 C++ 进行编码 (2023.Q1)

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧文章目录 最近更新的博客使用说明翻转单…...

4.Spring【Java面试第三季】

4.Spring【Java面试第三季】前言推荐4.Spring27_Aop的题目说明要求Spring的AOP顺序AOP常用注解面试题28_spring4下的aop测试案例业务类新建一个切面类MyAspect并为切面类新增两个注解&#xff1a;spring4springboot1.5.9pom测试类29_spring4下的aop测试结果aop正常顺序异常顺序…...

ZLibrary使用说明-Zlirbrary

ZLibrary使用说明如果您是一位书虫&#xff0c;那么ZLibrary是一个值得一试的网站。该网站提供了大量的免费电子书籍&#xff0c;涵盖了各种不同的主题和类别。下面是一些有关如何使用ZLibrary的详细说明&#xff1a;第1步&#xff1a;访问ZLibrary网站要使用ZLibrary&#xff…...

TwinCAT3第三方伺服电机——汇川SV660N使用

目录 一、第三方伺服在TC3中配置和使用 二、xml文件拷贝 ​编辑 三、IO中扫描伺服 四、工程测试 五、汇川伺服参数设置说明 一、第三方伺服在TC3中配置和使用 在倍福控制系统中使用第三方伺服可以参见本人另一篇博客&#xff0c;有详细教程说明。本文仅仅对SV660N伺服设置…...

进制转换(二进制,八进制,十进制,十六进制)涵盖整数与小数部分,内容的图片全为手写【详细图解】

各种进制之间的相互转换1. 各进制表示数1.1 数码1.2 基数1.3 位权2. 十进制转换为其他进制2.1 整数部分2.2 小数部分3. 其他进制转换为十进制4. 二进制转换为八进制5. 二进制转换为十六进制6. 八进制转换为十六进制1. 各进制表示数 二进制&#xff1a;0&#xff0c;1逢二进一 八…...

谈谈XR关键技术及VR/AR/MR/XR关系

一、先别被VR/AR/MR/XR搞晕&#xff0c;说说区别虚拟现实&#xff08;Virtual Reality&#xff0c;VR&#xff09;、增强现实&#xff08;Augmented Reality&#xff0c;AR&#xff09;等业务以其三维化、自然交互、空间计算等完全不同于当前移动互联网的特性&#xff0c;被认为…...

acwing1562 微博转发(宽搜)

微博被称为中文版的 Twitter。 微博上的用户既可能有很多关注者&#xff0c;也可能关注很多其他用户。 因此&#xff0c;形成了一种基于这些关注关系的社交网络。 当用户在微博上发布帖子时&#xff0c;他/她的所有关注者都可以查看并转发他/她的帖子&#xff0c;然后这些人…...

如何使用Arsenal快速部署功能强大的Bug Bounty工具

关于Arsenal Arsenal是一个功能强大且使用简单的Shell脚本&#xff08;Bash&#xff09;&#xff0c;该工具专为漏洞赏金猎人设计&#xff0c;在该工具的帮助下&#xff0c;我们可以轻松在自己环境中安装并部署目前社区中功能最为强大的网络侦查工具、漏洞扫描工具和其他安全研…...

(十)python网络爬虫(理论+实战)——正则表达式再讨论、常用正则表达式整理

系列文章目录 (1)python网络爬虫—快速入门(理论+实战)(一) (2)python网络爬虫—快速入门(理论+实战)(二) (3) python网络爬虫—快速入门(理论+实战)(三) (4)python网络爬虫—快速入门(理论+实战)(四) (5)...

MyBatis-Plus特性及插件整合

了解MyBatis-Plus 什么是MyBatis-Plus&#xff1f; mybatisPlus在mybatis的基础上继续针对CRUD操作进行优化&#xff0c;在原有的基础上提供了公共的接口BaseMapper&#xff0c;我们在创建接口Mapper时只需要继承这个接口即可调用MyBatisPlus已经提供好的方法&#xff0c;sql…...

应用篇|网络安全知识培训考试,答题小程序操作指引

网络安全知识培训考试&#xff0c;答题小程序操作指引关于全民防诈反诈宣传或者网络安全知识学习&#xff0c;如何进行组织一场微信线上答题考试&#xff1f;可以在小程序“护网专题信息安全知识竞答”&#xff0c;先创建一个学习单位/小组&#xff0c;再邀请成员加入单位/小组…...

官方不推荐@Autowired

1用lombok注解 2 构造器...

【牛客刷题专栏】0x0E:JZ6 从尾到头打印链表(C语言编程题)

前言 个人推荐在牛客网刷题(点击可以跳转)&#xff0c;它登陆后会保存刷题记录进度&#xff0c;重新登录时写过的题目代码不会丢失。个人刷题练习系列专栏&#xff1a;个人CSDN牛客刷题专栏。 题目来自&#xff1a;牛客/题库 / 在线编程 / 剑指offer&#xff1a; 目录前言问题…...

Zeppelin安装

1、下载Zeppelin 下载地址&#xff1a;Download 2.解压 [rootguo147 install]# tar -zxvf zeppelin-0.10.0-bin-all.tgz -C ../soft/ //修改文件名 [rootguo147 soft]# mv zeppelin-0.10.0-bin-all/ zeppelin 3.配置 //进入conf 目录 [rootguo147 conf]# pwd /opt/soft/zepp…...

【蓝桥杯选拔赛真题38】python目标值判断 青少年组蓝桥杯python 选拔赛STEMA比赛真题解析

目录 python目标值判断 一、题目要求 1、编程实现 2、输入输出 二、解题思路...

Python jieba分词如何添加自定义词和去除不需要长尾词

Python jieba分词如何添加自定义词和去除不需要长尾词 作者&#xff1a;虚坏叔叔 博客&#xff1a;https://xuhss.com 早餐店不会开到晚上&#xff0c;想吃的人早就来了&#xff01;&#x1f604; 通过如下代码&#xff0c;读取一个txt的高频词汇&#xff1a; # 找到高频词汇t…...

云打包苹果证书生成、上架和应用截屏攻略

在使用apicloud或hbuilderx这些跨端的开发工具开发移动应用的时候&#xff0c;假如是打包ios应用&#xff0c;是需要生成苹果证书、证书profile文件&#xff0c;和对应用上架的。首先要普及一个概念&#xff0c;苹果的应用是无法像安卓那样挂在自己的服务器上下载直接安装就可以…...

洛谷 U91193:棋盘覆盖问题 ← 分治法

【题目来源】https://www.luogu.com.cn/problem/U91193【问题描述】 在一个2^k * 2^k&#xff08;k≥0&#xff09;个方格组成的棋盘中&#xff0c;恰有一个方格与其他方格不同&#xff0c;称该方格为一特殊方格。现在用4种不同形状的 L型&#xff08;占3小格&#xff09;骨牌覆…...

基于OMAPL138+FPGA核心板多核软件开发组件MCSDK开发入门(下)

本文测试板卡为创龙科技 SOM-TL138F 是一款基于 TI OMAP-L138(定点/浮点 DSP C674x + ARM9)+ 紫光同创 Logos/Xilinx Spartan-6 低功耗 FPGA 处理器设计的工业级核心板。核心板内部OMAP-L138 与 Logos/Spartan-6 通过 uPP、EMIFA、I2C 通信总线连接,并通过工业级 B2B连接器引…...

熵,线性规划,半监督自监督聚类打标签

1.熵 信息熵是消除不确定性所需信息量的度量。 信息熵就是信息的不确定程度&#xff0c;信息熵越小&#xff0c;信息越确定。 对象的信息熵是正比于它的概率的负对数的&#xff0c;也就是 I©−log(pc) 其中n为事件的所有可能性。 为什么使用交叉熵&#xff1f;在机器学习…...

求极限方法总结

1.利用四则运算法则求极限 2.利用两个重要极限求极限 //0除以0型 //1的无穷次方型 3.利用等价无穷小替换替换求极限 //在等价替换时注意和差项 4.利用洛必达法则求极限 5.利用夹逼准则求极限 6.利用单调有界数列极限准则求极限 7.利用无穷小的性质求极限 8.利用函数的连续性…...

Flutter Scrollable 中ViewPort滚动原理

关于Flutter Sliver组件内容可以参考下面这位博主博客&#xff0c;写的已经非常好了&#xff0c;这里就不再赘述。 38、Flutter之 可滚动组件简介_flutter 可滑动_风雨「83」的博客-CSDN博客 通过阅读上面的博客&#xff0c;我们已经知道了Scrollable和Viewport基础概念&#…...

多目标粒子群结合极限学习机ELM求解帕累托前沿,MOPSO-ELM

目录 背影 parte前沿的定义 注意事项 基于多目标粒子群结合极限学习机的帕累托前沿求解帕累托前沿 主要参数 MATLAB代码 效果图 结果分析 展望 背影 在目标优化过程种,很多时候都两个或者多个目标,并且目标函数不能同时达到最优,鱼与熊掌不可兼得,这个时候可以通过求解帕…...

(二十)操作系统-信号量机制

文章目录一、知识预览二、前篇文章知识点回顾三、信号量机制四、信号量机制—整形信号量五、信号量机制—记录型信号量六、总结一、知识预览 二、前篇文章知识点回顾 进程互斥的四种软件实现方式&#xff1a;单标志法、双标志先检查、双标志后检查、Peterson算法。&#xff08;…...

ceph osd slow ops 检测

目的 常用的方法检测 ceph slow 问题 参考 yceph -scluster:id: 22908555-e596-4c2d-a1f6-34fcf4d3e935health: HEALTH_WARNDegraded data redundancy: 46384/12805029 objects degraded (0.362%), 145 pgs degraded, 122 pgs undersized309 slow ops, oldest one blocked…...

百度CTO王海峰:深度学习平台+大模型,夯实产业智能化基座

2月27日&#xff0c;中国人工智能学会首届智能融合产业论坛在成都顺利举办。本届论坛由中国人工智能学会&#xff08;CAAI&#xff09;主办&#xff0c;中国人工智能学会智能融合专委会、百度公司、深度学习技术及应用国家工程研究中心和电子科技大学联合承办。中国工程院多名院…...

【C++】vector的基本使用

难道向上攀爬的那条路&#xff0c;不是比站在顶峰更让人热血沸腾吗&#xff1f; 文章目录一、vector和string的联系与不同二、vector的扩容操作1.resize() &#xff08;缺省值为匿名对象&#xff09;&& reserve()2.reserve在g和vs上的扩容机制3.reserve异地扩容和shri…...

花生棒 做网站/企业培训课程ppt

欧版的小米「MIUI」是国外人修改的版本&#xff0c;适当去除了一些内置的APP 、去除广告、整合了「Google」框架和部分APP。目前欧版「MIUI 12」也发布了&#xff0c;之前没赶得上内测的用户&#xff0c;现在想体验「MIUI 12」也可以试试刷这个版本。雷锋哥还没有时间去刷&…...

做电影网站哪个源码好/网站搭建平台都有哪些

在讲解肺炎双球菌转化实验的时候&#xff0c;师生往往面临着如下几个疑问&#xff0c;试解答如下&#xff1a; ①加热能杀死细菌&#xff0c;却为何“杀不死”DNA&#xff1f; 对S型细菌加热到一定程度&#xff08;60度到100度&#xff09;&#xff0c;其蛋白质的分子结构受到破…...

织梦采集侠官方网站/汕头网站设计公司

满意答案灏忕粷2013.11.10采纳率&#xff1a;51% 等级&#xff1a;12已帮助&#xff1a;8367人#include void print(int n) {//递归打印整数n的最后一位if(n>10) print(n/10);switch(n%10) {case 0:printf("zero ");break;case 1:printf("one ");bre…...

机械网站建设价格/技能培训网

作者&#xff1a;SmartMax 链接&#xff1a;https://www.zhihu.com/question/30711594/answer/164335112 来源&#xff1a;知乎 著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 如下过程部署服务器。 这时候默认的安全组配置 &#xff0…...

设计师可以做兼职的网站/种子搜索引擎

点击上方“蓝色字”可关注我们&#xff01;暴走时评&#xff1a;日本最大的海运公司之一Nippon Yusen K.K.&#xff08;NYK&#xff09;正计划发行自己的数字货币。数字货币将提供给员工&#xff0c;以简化管理和运输&#xff0c;让员工更容易兑换当地货币。据称这种货币将与美…...

项目管理软件p6/seo关键词搜索优化

详见原文链接 http://www.killdb.com/2012/03/13/using-dd-command-to-copy-datafile-in-asm.html...