IOC ,全称 (Inverse Of Control) ,中文意思为:控制反转, Spring
框架的核心基于控制反转原理。

什么是控制反转?
控制反转是一种将组件依赖关系的创建和管理置于程序外部的技术。
由容器控制程序之间的关系,而不是由代码直接控制
由于控制权由代码转向了容器,所以称为反转

对象与对象之间的关系可以简单的理解为对象之间的依赖关系:
依赖关系:在
A 类需要类 B 的一个实例来进行某些操作,比如在类 A 的方法中需要调用类 B 的方法来完成功能,叫做 A 类依赖于 B
类。

一个需要特定的依赖的组件一般会涉及一个依赖对象,在 IOC 的概念中叫做目标 (target) 。换句话说, IOC
提供了这样的服务,使一个组件能够在它的整个生命周期中访问它的依赖和服务,用这种方法与它的依赖进行交互。总的来说, IOC
能够被分解为两种子类型:依赖注入和依赖查找。

(1) 依赖查找
比如使用 JNDI
注册一个数据库连接池的示例中,代码中从注册处获得依赖关系的 JNDI 查找 (JNDI lookups)

CODE:
initContext = new InitialContext();
// 获取数据源
DataSource
ds = (DataSource) initContext.lookup("java:comp/env/jdbc/mysql");
(2)
依赖注入
(Dependency Injection) 依赖注入:两个对象之间的依赖关系在程序运行时由外部容器动态的注入依赖行为方式称为依赖注入 (DI)
。 DI 是 IOC 的一种形式。

IoC 在应用开发中是一个非常有力的概念。如 Martin Flower 所述, IoC
的一种表现形式就是依赖性注射。依赖性注射用的是好莱坞原则, " 不要找我,我会找你的。 "
。换句来说,你的类不会去查找或是实例化它们所依赖的类。控制恰好是反过来的,某种容器会设置这种依赖关系。使用 IoC
常常使代码更加简洁,并且为相互依赖的类提供一种很好的方法。

依赖注入的三种实现类型:接口注入、 Setter
注入和构造器注入。
<1> 接口注入 (Type1)

CODE:
public class ClassA
{
private InterfaceB clzB;
public void doSomething() {
Ojbect obj
=Class.forName(Config.BImplementation).newInstance();
clzB =
(InterfaceB)obj;
clzB.doIt()
}
……
}
上面的代码中, ClassA 依赖于 InterfaceB
的实现,如何获得 InterfaceB 实现类的实例?传统的方法是在代码中创建 InterfaceB 实现类的实例,并将起赋予 clzB 。
而这样一来,
ClassA 在编译期即依赖于 InterfaceB
的实现。为了将调用者与实现者在编译期分离,于是有了上面的代码.
我们根据预先在配置文件中设定的实现类的类名
(Config.BImplementation) ,动态加载实现类,并通过 InterfaceB 强制转型后为 ClassA
所用。这就是接口注入的一个最原始的雏形。
而对于一个 Type1 型 IOC
容器而言,加载接口实现并创建其实例的工作由容器完成,见如下代码。

CODE:
public class ClassA
{
private InterfaceB clzB;
public Object doSomething(InterfaceB b)
{
clzB = b;
return clzB.doIt();
}
……
}
在运行期, InterfaceB
实例将由容器提供。
Type1 型 IOC 发展较早(有意或无意),在实际中得到了普遍应用,即使在 IOC
的概念尚未确立时,这样的方法也已经频繁出现在我们的代码中。
下面的代码大家应该非常熟悉:

CODE:
public class
MyServlet extends HttpServlet {
public void doGet(HttpServletRequest
request,HttpServletResponse response)throws ServletException, IOException { …… }
}
这也是一个 Type1 型注入, HttpServletRequest 和 HttpServletResponse 实例由 Servlet
Container 在运行期动态注入。
<2>Setter( 设值 ) 注入
(Type2)
各种类型的依赖注入模式中,设值注入模式在实际开发中得到了最广泛的应用。

CODE:
public class
ClassA {
private InterfaceB clzB;
public void setClzB(InterfaceB clzB)
{
this. clzB = clzB; }
……
}
<3> 构造器注入
(Type3)
依赖关系是通过类构造函数建立的
容器通过调用类的构造方法将其所需的依赖关系注入其中

CODE:
public
class DIByConstructor { private final DataSource dataSource;
public
DIByConstructor(DataSource ds) {
this.dataSource =
ds;
}
……
}
<4>
三种依赖注入方式的比较
接口注入:
接口注入模式因为历史较为悠久,在很多容器中都已经得到应用。但由于其在灵活性、易用性上不如其他两种注入模式,因而在
IOC 的专题世界内并不被看好。

Setter 注入:
对于习惯了传统 javabean 开发的程序员,通过 setter
方法设定依赖关系更加直观。
如果依赖关系较为复杂,那么构造子注入模式的构造函数也会相当庞大,而此时设值注入模式则更为简洁。
如果用到了第三方类库,可能要求我们的组件提供一个默认的构造函数,此时构造子注入模式也不适用。

构造器注入:
在构造期间完成一个完整的、合法的对象。
所有依赖关系在构造函数中集中呈现。
依赖关系在构造时由容器一次性设定,组件被创建之后一直处于相对“不变”的稳定状态。
只有组件的创建者关心其内部依赖关系,对调用者而言,该依赖关系处于“黑盒”之中。

总结:
可见,
Type3 和 Type2 模式各有千秋,而 Spring 、 PicoContainer 都对 Type3 和 Type2
类型的依赖注入机制提供了良好支持。这也就为我们提供了更多的选择余地。理论上,以 Type3 类型为主,辅之以 Type2
类型机制作为补充,可以达到最好的依赖注入效果,不过对于基于 Spring Framework 开发的应用而言, Type2 使用更加广泛。

Spring IOC三种注入方式(接口注入、setter注入、构造器注入)(摘抄)的更多相关文章

  1. spring ioc三种注入方式

    spring ioc三种注入方式 IOC ,全称 (Inverse Of Control) ,中文意思为:控制反转 什么是控制反转? 控制反转是一种将组件依赖关系的创建和管理置于程序外部的技术. 由容 ...

  2. Spring IOC 三种注入方式

    1.    接口注入 2.    setter注入 3.    构造器注入 对象与对象之间的关系可以简单的理解为对象之间的依赖关系:A类需要B类的一个实例来进行某些操作,比如在A类的方法中需要调用B类 ...

  3. Spring IOC 三种注入方式(构造器,setter,接口)

    Spring的依赖注入有三种方式: 1,构造器注入 2,setter注入 3,接口注入 下面我给大家介绍一下这三种注入 1.构造器注入 构造器注入主要是依赖于构造方法去实现,构造方法可以是有参也可以是 ...

  4. Spring bean三种创建方式

    spring共提供了三种实例化bean的方式:构造器实例化(全类名,反射).工厂方法(静态工厂实例化   动态工厂实例化)和FactoryBean ,下面一一详解: 1.构造器实例化 City.jav ...

  5. 哪种依赖注入方式你建议使用,构造器注入,还是 Setter方法注入?

    你两种依赖方式都可以使用,构造器注入和Setter方法注入.最好的解决方案是用构造器参数实现强制依赖,setter方法实现可选依赖.

  6. Spring事务-三种实现方式

    一.引入JAR文件: 二.开始搭建分层架构---创建账户(Account)和股票(Stock)实体类 Account: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...

  7. Spring MVC三种返回方式

    spring mvc处理方法支持如下的返回方式:ModelAndView, Model, ModelMap, Map,View, String, void. 下面一一进行说明: 1.ModelAndV ...

  8. Bean的三种实例化方式

    在面向对象程序中,如要使用某个对象,就需要先实例化这个对象.同样的,在Spring中,要想使用容器中的Bean,也需要实例化Bean.实例化Bean有三种方式,分别是:构造器实例化.静态工厂实例化.实 ...

  9. Spring的三种通过XML实现DataSource注入方式

    Spring的三种通过XML实现DataSource注入方式: 1.使用Spring自带的DriverManagerDataSource 2.使用DBCP连接池 3.使用Tomcat提供的JNDI

随机推荐

  1. Android UiAutomator 自动化测试环境搭建---新手1

    1.首先需要准备的工具有 1.java jdk 2. android开发工具 adt 3.ant 安装包(如果下载adt里面有) 2.首先安装java环境,jdk这个百度就可以了. 3.android ...

  2. Output in PowerShell

    Reference article: https://rkeithhill.wordpress.com/2007/09/16/effective-powershell-item-7-understan ...

  3. 玩转无线 — GNURADIO 简单运用

    大家好, 我是Insight-labs的旺财,这里放出个旺财在Bsides Toronto 2013 会上RF-Ninjia Hacking议题中的一个案例,随着物联网越来越火热,而物联网又离不开无线 ...

  4. 从51跳cortex-m0学习2——程序详解

    跳cortex-m0——思想转变>之后又一入门级文章,在此不敢请老鸟们过目.不过要是老鸟们低头瞅了一眼,发现错误,还请教育之,那更是感激不尽.与Cortex在某些操作方式上的异同,让自己对Cor ...

  5. Qt 智能指针学习(7种QT的特有指针)

    从内存泄露开始? 很简单的入门程序,应该比较熟悉吧 ^_^ #include <QApplication> #include <QLabel> int main(int arg ...

  6. selenium - Headless Browser and scraping - solutions - Stack Overflow

    yum install pygtk2-devel   selenium - Headless Browser and scraping - solutions - Stack Overflow Hea ...

  7. c#Winform程序的toolStripButton自己定义背景应用演示样例源代码

    C# Winform程序的toolStrip中toolStripButton的背景是蓝色的,怎样改变背景及边框的颜色和样式呢? 实现此功能须要重写toolStripButton的Paint方法 这里仅 ...

  8. Sass入门——基本特性-基础

    本文来自慕课网大漠 声明变量 三个部分:1.声明变量的符号"$"2.变量名称3.赋予变量的值 $brand-primary : darken(#428bca, 6.5%) !def ...

  9. GIT简易使用流程

    git是目前世界上最先进的分布式版本控制系统(摘自廖雪峰官网) 首先需要在系统上安装git: Windows系统在这下载: RHEL/Centos/Fedora用户可以用以下命令安装:yum -y i ...

  10. 转: seajs手册与文档之 -- require规则

    require 规则 正确拼写 不要修改 使用直接量 动态依赖的小提示 书写规则 使用 SeaJS 书写模块代码时,需要遵循一些简单规则: 1. 正确拼写 在模块代码中,第一个参数 必须 命名为 re ...