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

什么是DI(依赖注入),依赖注入的原理

这篇文章主要介绍了Spring当中的依赖注入(DI),以及他的简单实现原理,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

什么是依赖注入?

  • Dependency Injection。它是 spring 框架核心 ioc 的具体实现。
  • 我们的程序在编写时,把对象的创建交给了 spring,但是代码中不可能出现没有依赖的情况。通过容器只是降低他们的依赖关系,但不会消除。例如:我们的业务层仍会调用持久层的方法。
  • 那这种业务层和持久层的依赖关系,在使用 spring 之后,就让 spring 来维护了。简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取。

依赖注入的原理

所谓的依赖注入其实就是通过反射给成员变量赋值,这里的成员变量就是我们所说的依赖。比如TestController当中有个TestService对象,他需要依赖TestService对象当中的方法,那么TestService就是TestController的依赖。

这里就考验到了通过反射我们有几种方式可以给TestService赋值,一共有如下三种:

  1. 通过构造器给变量赋值
  2. 通过set方法给变量赋值
  3. 直接给属性赋值

下面我们直接通过案例来理解:

下面是正常的一个controller调用service的过程,一般我们在TestService这里都会使用一个@Autowired或者@Resource注解,表示由spring进行注入,Spring扫描注解的时候就知道这个变量需要注入,于是他便会去容器当中寻找该对象的实例,然后通过反射将其注入到变量当中。

public class TestController {private TestService testService;public TestController() {System.out.println("TestController初始化了");}public TestController(TestService testService) {this.testService = testService;}public void setTestService(TestService testService) {this.testService = testService;}public void method1() {testService.method1();}
}

然后service代码如下:

public class TestService {public TestService() {System.out.println("TestService初始化了");}public void method1() {System.out.println("method1方法执行了");}
}

(1)通过构造器给变量赋值:

@Test
public void test5() throws Exception {Class cls = Class.forName("com.gzl.cn.controller.TestController");Constructor constructor = cls.getConstructor(TestService.class);TestController testController = (TestController)constructor.newInstance(new TestService());testController.method1();
}

运行结果:

(2)通过set方法给变量赋值:

public static void main(String[] args) throws Exception{Class cls = Class.forName("com.gzl.cn.controller.TestController");// 根据方法名和参数类型找到对应的set方法Method mtd = cls.getMethod("setTestService", TestService.class);// 创建TestController的实例TestController testController = (TestController)cls.newInstance(); 执行TestController实例的这个方法,正常来说TestService不是new的,他会看看容器有没有,有的话取容器的TestService testService = new TestService();mtd.invoke(testController, testService); 这时候已经完成属性的注入了testController.method1();
}

运行结果:

(3)直接给属性赋值:

@Test
public void test6() throws Exception {Class cls = Class.forName("com.gzl.cn.controller.TestController");TestController testController = (TestController) cls.newInstance();// 这时候假如直接访问,会异常,因为testService属性此刻还为空//testController.method1();// 这里注意要使用getDeclaredField,不要用getField,因为testService属性并不是publicField testServiceField = cls.getDeclaredField("testService");// 这里要设置true,不然修改private修饰符的属性会异常testServiceField.setAccessible(true);testServiceField.set(testController, new TestService());testController.method1();
}

运行结果:

依赖注入本质上就是基于这三种反射注入的方式进行的注入的,只不过给我们提供了相应的注解,方便我们使用,并且他还能够很好的结合IOC容器来使用!

http://www.lryc.cn/news/2417877.html

相关文章:

  • 数据库的索引
  • 用AVPlayer播放视频
  • 说走就走的「Windows」—— Windows To Go 制作详解
  • 算法篇-----粒子群算法
  • linux解压缩命令大全
  • html网页制作——HTML5响应式个人简历网站模板 web前端网页制作课作业
  • 项目介绍——面向对象与软件工程实验四
  • flex与bison入门,编译原理:flex编写词法分析器(使用windows环境)
  • NIVIDIA 硬解码学习2
  • 泛函分析的優勢在數值解析中:高效計算與準確度的平衡
  • 向量的点乘和叉乘
  • 打印机连接三种方式
  • Netbeans 适配C/C++、JAVA防坑秘笈
  • JS中几个getElementByXXX方法的区别
  • Varnish的基本应用详解
  • 使用autoit,可以节省您很多时间
  • 图文结合!非常详细Linux简介与安装!
  • CSS行高——line-height
  • Android面试:Invalidate、RequestLayout
  • Java基础—正则表达式
  • Font Awesome Icon Picker 教程
  • 开源全能免费的视频下载神器:Hitomi Downloader
  • PIM介绍
  • 通俗讲解:什么是Web
  • LTP简介
  • 排序算法——七种排序算法汇总,详细(Java)
  • 算法基础2 —— OJ入门以及暴力枚举
  • 揭秘!“真假美猴王事件”其实是如来的一次运维事故
  • Java面试题大全带答案
  • ![CDATA[]]介绍及使用方法