Spring核心之依赖注入(三)
来源:互联网 发布:知乎 毕业一年后 编辑:程序博客网 时间:2024/06/08 09:17
依赖注入DI
Java应用中(无论像Applet的小应用还是多层结构的企业及应用),都存在大量的A对象需要调用B对象方法的情形,这种情形被Spring称为依赖,即A对象依赖B对象。Java应用大多由一些相互调用的对象构成的,Spring把这种互相调用的关系称为依赖关系。假如A组件调用了B组件的方法,即可称组件A依赖B组件。
Spring框架的核心功能有两个。
1. Spring容器作为超级大工厂,负责创建、管理所有的Java对象,这些Java对象被称为Bean。
2. Spring容器管理容器中Bean之间的依赖关系,Spring使用一种被称为“依赖注入”的方式来管理Bean之间的依赖关系。
使用依赖注入,不仅可以为Bean注入普通的属性 值,还可以注入其他Bean的引用。通过这种依赖注入,JavaEE应用中的各种组件不需要以硬编码方式耦合在一起,甚至无需使用工厂模式。使用依赖注入,当某个Java实例需要其他Java实例时,系统自动提供所需要的实例,无需程序显式获取。
Rod Johnson是第一个高度重视以配置文件来管理Java实例的协作关系的人,他称这种方式为控制反转IoC(Invension of Control)。Martine Flower称这种方式为依赖注入DI(Dependency Injection)。
当某个Java对象(调用者)需要调用另一个Java对象(被依赖对象)的方法时,传统一般的方法有两种:
1原始模式: 调用者主动创建被依赖对象,然后再调用被依赖对象的方法。
2. 简单工厂模式:调用者先找到被依赖对象的工厂,然后主动通过工厂去获取依赖对象,最后再调用被依赖对象的方法。
对于第一种方式,由于调用者需要通过形如“new 被依赖对象构造器();”的代码创建被依赖对象,会导致调用者与被依赖对象实现类的硬编码耦合,不利于项目升级维护。
对于简单工厂模式,大致需要把握三点:1. 调用者面向被依赖对象的接口编程;2. 将被依赖对象的创建交给工厂完成;3. 调用者通过工厂获得被依赖组件。通过三点改造,可以保证调用者只与被依赖对象的接口耦合,避免了类层次的硬编码耦合。缺点是:调用组件需要主动通过工厂获取被依赖对象,导致调用组件和被依赖对象工厂的耦合。
使用Spring框架后,调用者不用主动获取依赖对象,只要被动地接受Spring容器为调用者的成员变量赋值即可(通过配置< property…/>子元素,Spring就会执行对应的setter方法为调用者的成员变量赋值)。调用者调用被依赖对象的方式由原来的主动获取变成了被动接受,所有Jody Johnson称之为反转控制。
从Spring容器的角度看,Spring容器负责将被依赖对象赋值给调用者的成员变量,相当于为调用者注入它依赖的实例,故Martine Flowler将这种方式称为依赖注入。
下面通过一个问题描述增强对依赖注入的理解:
问题:一个人(Java实例,调用者)需要一把斧头(Java实例,被依赖对象)。
在原始社会,几乎没有社会分工。需要斧头的人(调用者)只能自己去磨一把斧头(被依赖对象),相当于Java程序里调用者自己创建依赖对象,通常用new关键字调用构造器来创建一个被依赖对象。
进入工业社会,工厂出现了,斧头不用下有普通人磨了,而在工厂里被生产出来,此时需要斧头的人(调用者)找到工厂,购买斧头(无需关心斧头的制作过程),对应简单工厂设计模式,调用者只需定位工厂,无需理会被依赖对象的具体实现。
进入“共产主义社会”,需要斧头的人甚至无需定位工厂,“坐等”社会供应即可。调用者无需关心被依赖对象的实现,无需理会工厂,等待Spring依赖注入。
依赖注入一般有设值注入和构造注入。
设值注入
IoC容器使用成员变量的setter方法注入被依赖对象。该方法简单、直接,在Spring的依赖注入里大量使用。
<bean id="helloWorld" class="com.afy.spring.beans.HelloWorld"> <!-- 设值(set 方法)注入为属性赋值 --> <property name="name" value="Spring"></property></bean>
构造注入
这种方式在构造实例时,已经完成了依赖关系的初始化,这种利用构造器来设值依赖的方式,被称为构造注入。
可以简单地理解成,驱动Spring在底层以反射方式执行带指定参数的构造器来创建对象,当执行带参数的构造器时,就可以利用构造器参数对成员变量初始化,这就是构造注入的本质。
< bean…/>默认驱动Spring调用无参构造器来创建对象,驱动Spring调用有参数构造器是通过< constructoer…/>子元素,每个< constructor-arg…/>子元素代表一个构造器参数,如果< bena…/>元素包含多个< constructor-arg…/>子元素,就会驱动Spring调用多个参数的构造器来创建对象。
<bean id="helloWorld" class="com.afy.spring.beans.HelloWorld"> <!-- 设值(set 方法)注入为属性赋值 --> <constructor-arg ref="Axe"/></bean>
- Spring核心之依赖注入(三)
- spring核心之依赖注入(一)设置注入
- (三)Spring 依赖注入
- Spring的核心机制(依赖注入)
- Spring核心机制(依赖注入IOC)
- Spring框架(三)依赖注入之注解方式
- Spring学习(三)之依赖注入实现
- Spring核心机制(依赖注入)
- spring核心机制:依赖注入
- Spring核心机制:依赖注入
- Spring核心机制-依赖注入
- Spring核心机制:依赖注入
- Spring核心机制:依赖注入
- SSH深度历险(八) 剖析SSH核心原理+Spring依赖注入的三种方式
- Spring-----3、Spring的核心机制(依赖注入)
- Spring学习笔记(三)依赖注入
- spring之依赖注入
- Spring之依赖注入
- Poj 2907 Collecting Beepers【枚举+最短路径】
- MySQL自定义函数
- Android 学习资料收集
- 关于Unicode编码的闲谈
- hdoj1002
- Spring核心之依赖注入(三)
- poj 1088 滑雪
- Android开发艺术探索学习笔记之Activity(1)生命周期
- OSGI入门环境搭建及相关概念
- [kuangbin带你飞]专题一 简单搜索-J - Fire!
- Android活动被回收了的处理方式
- Codeforces 667C Reberland Linguistics (DP)
- 面试之路(16)-归并排序详解(MergeSort)递归和非递归实现
- MySQL 下 ROW_NUMBER / DENSE_RANK / RANK 的实现