分享Spring中接口注入的三种方式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分享Spring中接口注入的三种方式相关的知识,希望对你有一定的参考价值。

参考技术A   下面是Spring开发指南中所说的三种注入方式 我看了 但不太懂 大家也看看 看有没有更好的理解方式 请给于指点 我的Email      Type 接口注入     我们常常借助接口来将调用者与实现者分离 如:  public class ClassA   private InterfaceB clzB;  public init()   Ojbect obj =  Class forName(Config BImplementation) newInstance();  clzB = (InterfaceB)obj;    ……      上面的代码中 ClassA依赖于InterfaceB的实现 如何获得InterfaceB实现类的实例?传统的方法是在代码中创建InterfaceB实现类的实例 并将起赋予clzB     而这样一来 ClassA在编译期即依赖于InterfaceB的实现 为了将调用者与实现者在编译期分离 于是有了上面的代码 我们根据预先在配置文件中设定的实现类的类名 动态加载实现类 并通过InterfaceB强制转型后为ClassA所用     这就是接口注入的一个最原始的雏形     而对于一个Type 型IOC容器而言 加载接口实现并创建其实例的工作由容器完成 如J EE开发中常用的Context lookup(ServletContext getXXX) 都是Type 型IOC的表现形式     Apache Avalon是一个典型的Type 型IOC容器      Type 构造子注入     构造子注入 即通过构造函数完成依赖关系的设定 如   public class DIByConstructor   private final DataSource dataSource;  private final String message;  public DIByConstructor(DataSource ds String msg)   this dataSource = ds;  ssage = msg;    ……      可以看到 在Type 类型的依赖注入机制中 依赖关系是通过类构造函数建立 容器通过调用类的构造方法 将其所需的依赖关系注入其中     PicoContainer(另一种实现了依赖注入模式的轻量级容器)首先实现了Type 类型的依赖注入模式      Type 设值注入     在各种类型的依赖注入模式中 设值注入模式在实际开发中得到了最广泛的应用(其中很大一部分得力于Spring框架的影响)     在笔者看来 基于设置模式的依赖注入机制更加直观 也更加自然 Quick Start中的示例 就是典  SpringFrameWork Developer s Guide Version   September So many open source projects Why not Open your Documents?    型的设置注入 即通过类的setter方法完成依赖关系的设置      几种依赖注入模式的对比总结     接口注入模式因为具备侵入性 它要求组件必须与特定的接口相关联 因此并不被看好 实际使用有限     Type 和Type 的依赖注入实现模式均具备无侵入性的特点 在笔者看来 这两种实现方式各有特点 也各具优势(一句经典废话?)      Type 构造子注入的优势      . 在构造期即创建一个完整 合法的对象 对于这条Java设计原则 Type 无疑是最好的响应者      . 避免了繁琐的setter方法的编写 所有依赖关系均在构造函数中设定 依赖关系集中呈现 更加易读      . 由于没有setter方法 依赖关系在构造时由容器一次性设定 因此组件在被创建之后即处相对 不变 的稳定状态 无需担心上层代码在调用过程中执行setter方法对组件依赖关系产生破坏 特别是对于Singleton模式的组件而言 这可能对整个系统产生重大的影响      . 同样 由于关联关系仅在构造函数中表达 只有组件创建者需要关心组件内部的依赖关系 对调用者而言 组件中的依赖关系处于黑盒之中 对上层屏蔽不必要的信息 也为系统的层次清晰性提供了保证      通过构造子注入 意味着我们可以在构造函数中决定依赖关系的注入顺序 对于一个大量依赖外部服务的组件而言 依赖关系的获得顺序可能非常重要 比如某个依赖关系注入的先决条件是组件的DataSource及相关资源已经被设定      Type 设值注入的优势      对于习惯了传统JavaBean开发的程序员而言 通过setter方法设定依赖关系显得更加直观 更加自然      如果依赖关系(或继承关系)较为复杂 那么Type 模式的构造函数也会相当庞大(我们需要在构造函数中设定所有依赖关系) 此时Type 模式往往更为简洁      对于某些第三方类库而言 可能要求我们的组件必须提供一个默认的构造函数(如Struts中的Action) 此时Type 类型的依赖注入机制就体现出其局限性 难以完成我们期望的功能     可见 Type 和Type 模式各有千秋 而Spring PicoContainer都对Type 和Type 类型的依赖注入机制提供了良好支持 这也就为我们提供了更多的选择余地 __________理论上 以Type 类型为主 辅之以Type 类型机制作为补充 可以达到最好的依赖注入效果 不过对于基于Spring Framework开发的应用而言 Type 使用更加广泛 lishixinzhi/Article/program/Java/ky/201311/28347

Spring IOC的三种注入方式

Spring IOC三种注入方式:

1.    接口注入

2.    getter,setter方式注入

3.    构造器注入

对象与对象之间的关系可以简单的理解为对象之间的依赖关系:
A类需要B类的一个实例来进行某些操作,比如在A类的方法中需要调用B类的方法来完成功能,叫做A类依赖于B类.
控制反转是一种将组件依赖关系的创建和管理置于程序外部的技术,由容器控制程序之间的关系,而不是由代码直接控制.

1.接口注入

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所用,这就是接口注入的一个最原始的雏形.

public class ClassA {
  private InterfaceB clzB;
  public Object doSomething(InterfaceB b) {
    clzB = b;
    return clzB.doIt();
  }
……
}

上面代码中,加载接口实现并创建其实例的工作由容器完成.
在运行期,InterfaceB实例将由容器提供.即使在IOC的概念尚未确立时,这样的方法也已经频繁出现在我们的代码中.

public class MyServlet extends HttpServlet {
  public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {
    ……
  }
}

HttpServletRequest和HttpServletResponse实例由Servlet Container在运行期动态注入.

2.Setter设置注入
基于设置模式的依赖注入机制更加直观,也更加自然.

public class ClassA {
  private InterfaceB clzB;
  public void setClzB(InterfaceB clzB) {
    this.clzB = clzB;
  }
……
}

3.构造器注入

public class DIByConstructor {
  private final DataSource dataSource;
  public DIByConstructor(DataSource ds) {
    this.dataSource = ds;
  }
……
}

构造器注入,即通过构造函数完成依赖关系的设定,容器通过调用类的构造方法将其所需的依赖关系注入其中.

三种注入方式比较:

接口注入:

接口注入模式因为具备侵入性,它要求组件必须与特定的接口相关联,因此并不被看好,实际使用有限。

Setter 注入:

对于习惯了传统 javabean 开发的程序员,通过 setter 方法设定依赖关系更加直观。

如果依赖关系较为复杂,那么构造子注入模式的构造函数也会相当庞大,而此时设值注入模式则更为简洁。

如果用到了第三方类库,可能要求我们的组件提供一个默认的构造函数,此时构造子注入模式也不适用。

构造器注入:

在构造期间完成一个完整的、合法的对象。

所有依赖关系在构造函数中集中呈现。

依赖关系在构造时由容器一次性设定,组件被创建之后一直处于相对“不变”的稳定状态。

只有组件的创建者关心其内部依赖关系,对调用者而言,该依赖关系处于“黑盒”之中。

总结

Spring使用注入方式,为什么使用注入方式,这系列问题实际归结起来就是一句话,Spring的注入和IoC(本人关于IoC的阐述)反转控制是一回事。

理论上:第三种注入方式(构造函数注入)在符合java使用原则上更加合理,第二种注入方式(setter注入)作为补充。

实际上:我个人认为第二种注入方式(setter注入)可以取得更加直观的效果,在使用工作上有不可比拟的优势,所以setter注入依赖关系应用更加广泛。

以上是关于分享Spring中接口注入的三种方式的主要内容,如果未能解决你的问题,请参考以下文章

spring的三种注入方式是啥?

Spring IOC的三种注入方式

spring的注入方式有几种

Spring-DI的三种实现方式以及优劣

Spring-DI的三种实现方式以及优劣

Spring的依赖注入(DI)三种方式