理解Spring中的依赖注入和控制反转
依赖注入(Dependency Injection)是一种面向对象编程的设计模式,用于解决对象之间的依赖关系。它的基本思想是将对象的创建和管理工作交给容器来完成,而不是在应用程序中手动创建和管理对象,从而达到松耦合、易维护、易测试的目的。依赖注入的实现原理是通过反射机制实现的。当一个对象需要依赖其他对象时,容器会通过反射机制查找和创建相应的对象,并将它们注入到需要依赖的对象中。这样,对象之间的依赖关系就由容器来维护,开发者只需要通过配置文件或注解等方式,告诉容器如何创建和注入对象。
在 Spring 框架中,依赖注入是通过 IoC(Inverse of Control,控制反转)实现的。IoC 容器在启动时,会扫描应用程序中的 Bean,并为每个 Bean 创建一个实例,并将它们存储在容器中。当其他 Bean 需要依赖这些 Bean 时,容器会自动将它们注入到需要依赖的 Bean 中。
具体来说,Spring 框架中的依赖注入主要有以下三种方式:
基于构造函数的依赖注入:通过构造函数来注入依赖项。
基于 Setter 方法的依赖注入:通过 Setter 方法来注入依赖项。
基于字段注入:通过直接将依赖项注入到类的字段中来实现。
那么什么是控制反转IoC呢?IoC 的基本思想是将程序中对象之间的依赖关系由程序员手动控制转变为由容器自动控制,即将对象的创建和管理工作交给容器来完成,而不是在应用程序中手动创建和管理对象。
依赖注入实际是通过反射机制实现的,反射机制实现依赖注入的具体步骤如下所示:
读取配置文件或者注解,获取依赖关系信息。
遍历依赖关系,通过反射机制获取依赖对象的类类型,然后使用 Class 类的 newInstance() 方法创建对象实例。
如果依赖对象有构造器参数,则通过递归调用实现构造器注入。
如果依赖对象有 setter 方法,则通过反射调用 setter 方法实现属性注入。
既然依赖注入本质是通过反射机制实现,那么什么是反射机制呢?反射机制是指在程序运行时动态获取类信息、访问或修改对象属性、调用对象方法等操作的一种机制。Java 反射机制提供了一组 API,使得程序能够在运行时获取并使用类的信息,而不需要在编译期间就确定。Java 反射机制提供了以下一些常用的 API:
Class 类:表示一个类的信息,可以获取类名、包名、父类、接口、构造器、属性、方法等信息。
Constructor 类:表示一个类的构造器信息,可以获取构造器的参数、修饰符、注解等信息。
Field 类:表示一个类的属性信息,可以获取属性名、类型、修饰符、注解等信息。
Method 类:表示一个类的方法信息,可以获取方法名、返回类型、参数、修饰符、注解等信息。
Modifier 类:提供了一组静态方法,可以判断一个类、方法或属性的修饰符,如 public、private、static、final 等。
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个步骤:
配置Bean
在Spring中,Bean的配置可以通过XML配置文件、注解或Java代码来实现。在配置中可以定义Bean的属性、依赖关系等信息,这部分是程序员编写,例如通过注解@Autowired等进行配置。
容器创建Bean
当Spring容器(容器是Spring框架的核心,它负责创建、管理和调用Bean)启动时,它会根据配置文件中的定义,通过Java的反射机制创建所有需要的Bean,并将它们存储在容器中。
注入依赖
在容器创建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中的依赖注入和控制反转
依赖注入(Dependency Injection)是一种面向对象编程的设计模式,用于解决对象之间的依赖关系。它的基本思想是将对象的创建和管理工作交给容器来完成,而不是在应用程序中手动创建和管理对象,从而达到松耦合、易维护、易…...
XXL-JOB
XXL-JOB介绍 XXL-JOB是一个轻量级分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。 官网:https://www.xuxueli.com/xxl-job/ 文档:分布式任务调度…...
「牛客网C」初学者入门训练BC134,BC136
🐶博主主页:ᰔᩚ. 一怀明月ꦿ ❤️🔥专栏系列:线性代数,C初学者入门训练 🔥座右铭:“不要等到什么都没有了,才下定决心去做” 🚀🚀🚀大家觉不错…...
华为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并为切面类新增两个注解:spring4springboot1.5.9pom测试类29_spring4下的aop测试结果aop正常顺序异常顺序…...
ZLibrary使用说明-Zlirbrary
ZLibrary使用说明如果您是一位书虫,那么ZLibrary是一个值得一试的网站。该网站提供了大量的免费电子书籍,涵盖了各种不同的主题和类别。下面是一些有关如何使用ZLibrary的详细说明:第1步:访问ZLibrary网站要使用ZLibraryÿ…...
TwinCAT3第三方伺服电机——汇川SV660N使用
目录 一、第三方伺服在TC3中配置和使用 二、xml文件拷贝 编辑 三、IO中扫描伺服 四、工程测试 五、汇川伺服参数设置说明 一、第三方伺服在TC3中配置和使用 在倍福控制系统中使用第三方伺服可以参见本人另一篇博客,有详细教程说明。本文仅仅对SV660N伺服设置…...
进制转换(二进制,八进制,十进制,十六进制)涵盖整数与小数部分,内容的图片全为手写【详细图解】
各种进制之间的相互转换1. 各进制表示数1.1 数码1.2 基数1.3 位权2. 十进制转换为其他进制2.1 整数部分2.2 小数部分3. 其他进制转换为十进制4. 二进制转换为八进制5. 二进制转换为十六进制6. 八进制转换为十六进制1. 各进制表示数 二进制:0,1逢二进一 八…...
谈谈XR关键技术及VR/AR/MR/XR关系
一、先别被VR/AR/MR/XR搞晕,说说区别虚拟现实(Virtual Reality,VR)、增强现实(Augmented Reality,AR)等业务以其三维化、自然交互、空间计算等完全不同于当前移动互联网的特性,被认为…...
acwing1562 微博转发(宽搜)
微博被称为中文版的 Twitter。 微博上的用户既可能有很多关注者,也可能关注很多其他用户。 因此,形成了一种基于这些关注关系的社交网络。 当用户在微博上发布帖子时,他/她的所有关注者都可以查看并转发他/她的帖子,然后这些人…...
如何使用Arsenal快速部署功能强大的Bug Bounty工具
关于Arsenal Arsenal是一个功能强大且使用简单的Shell脚本(Bash),该工具专为漏洞赏金猎人设计,在该工具的帮助下,我们可以轻松在自己环境中安装并部署目前社区中功能最为强大的网络侦查工具、漏洞扫描工具和其他安全研…...
(十)python网络爬虫(理论+实战)——正则表达式再讨论、常用正则表达式整理
系列文章目录 (1)python网络爬虫—快速入门(理论+实战)(一) (2)python网络爬虫—快速入门(理论+实战)(二) (3) python网络爬虫—快速入门(理论+实战)(三) (4)python网络爬虫—快速入门(理论+实战)(四) (5)...
MyBatis-Plus特性及插件整合
了解MyBatis-Plus 什么是MyBatis-Plus? mybatisPlus在mybatis的基础上继续针对CRUD操作进行优化,在原有的基础上提供了公共的接口BaseMapper,我们在创建接口Mapper时只需要继承这个接口即可调用MyBatisPlus已经提供好的方法,sql…...
应用篇|网络安全知识培训考试,答题小程序操作指引
网络安全知识培训考试,答题小程序操作指引关于全民防诈反诈宣传或者网络安全知识学习,如何进行组织一场微信线上答题考试?可以在小程序“护网专题信息安全知识竞答”,先创建一个学习单位/小组,再邀请成员加入单位/小组…...
官方不推荐@Autowired
1用lombok注解 2 构造器...
【牛客刷题专栏】0x0E:JZ6 从尾到头打印链表(C语言编程题)
前言 个人推荐在牛客网刷题(点击可以跳转),它登陆后会保存刷题记录进度,重新登录时写过的题目代码不会丢失。个人刷题练习系列专栏:个人CSDN牛客刷题专栏。 题目来自:牛客/题库 / 在线编程 / 剑指offer: 目录前言问题…...
Zeppelin安装
1、下载Zeppelin 下载地址: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分词如何添加自定义词和去除不需要长尾词 作者:虚坏叔叔 博客:https://xuhss.com 早餐店不会开到晚上,想吃的人早就来了!😄 通过如下代码,读取一个txt的高频词汇: # 找到高频词汇t…...
云打包苹果证书生成、上架和应用截屏攻略
在使用apicloud或hbuilderx这些跨端的开发工具开发移动应用的时候,假如是打包ios应用,是需要生成苹果证书、证书profile文件,和对应用上架的。首先要普及一个概念,苹果的应用是无法像安卓那样挂在自己的服务器上下载直接安装就可以…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...
