一次被问到IOC的注入方式,当时脑袋一阵混乱,不知道噻。于是google了一下,发现众说纷纭,有说三种的,有说四种的。都滚犊子吧,还是看看官方文档吧。

DI exists in two major variants, Constructor-based dependency injection and Setter-based dependency injection.

从官方文档上也看不出到底有几种注入方式,从上面这段引文中仅仅能知道主要有两种:构造器注入方式和Setter注入方式。

构造器注入方式

构造器注入方式是通过Spring容器调用含参构造函数实现的,每个参数都相当于一个依赖。这种方式和把参数传递给工厂方法来构造bean是非常相似的。

构造器参数解析

构造器通过参数类型匹配,如果参数类型都很明确,在bean实例化时,通过参数顺序来选择合适的构造函数。示例如下:

package x.y;

public class Foo {

  public Foo(Bar bar, Baz baz) {
// ...
}
}

不存在参数类型不确定性是指Bar和Baz不在一个继承体系内(除Object体系外),因此在配置<constructor-arg/>时,不需要特别指定参数的索引值或类型。如下:

<beans>
<bean id="foo" class="x.y.Foo">
<constructor-arg ref="bar"/>
<constructor-arg ref="baz"/>
</bean> <bean id="bar" class="x.y.Bar"/>
<bean id="baz" class="x.y.Baz"/> </beans>

就像上面例子中那样,当被其他bean引用时,就已经可以确定类型了。但是构造器参数中使用了像这样<value>true<value>的基本数据类型,在没有提示的前提下Spring是没办法确定类型的,就像下面这个例子:

package examples;

public class ExampleBean {

  // No. of years to the calculate the Ultimate Answer
private int years; // The Answer to Life, the Universe, and Everything
private String ultimateAnswer; public ExampleBean(int years, String ultimateAnswer) {
this.years = years;
this.ultimateAnswer = ultimateAnswer;
}
}
参数类型匹配构造器

使用简单类型作为参数时,指定type属性值,这样Spring容器就可以通过类型匹配来选择合适的构造器。这样上面那个问题就可以这样解决:

<bean id="exampleBean" class="examples.ExampleBean">
<constructor-arg type="int" value="7500000"/>
<constructor-arg type="java.lang.String" value="42"/>
</bean>
构造器参数索引值

根据构造器中参数的索引值来指定index属性值来匹配参数。如下:

<bean id="exampleBean" class="examples.ExampleBean">
<constructor-arg index="0" value="7500000"/>
<constructor-arg index="1" value="42"/>
</bean>

指定索引值就可以解决一个构造器使用两个相同类型参数的问题。注意索引值是从0开始的。

构造器参数名称

从Spring3.0起,可以使用构造器参数名称来消除参数模糊问题。

<bean id="exampleBean" class="examples.ExampleBean">
<constructor-arg name="years" value="7500000"/>
<constructor-arg name="ultimateanswer" value="42"/>
</bean>

需要特殊说明的是:如果要使用参数名称,那么需要在编译的时候启用debug标志,这样Spring才能用构造器中找到参数名称。如果不能或者不想开启debug模式,可以使用@ConstructorProperties注解来指定构造器中参数的名称。示例如下:

package examples;

public class ExampleBean {

  // Fields omitted

  @ConstructorProperties({"years", "ultimateAnswer"})
public ExampleBean(int years, String ultimateAnswer) {
this.years = years;
this.ultimateAnswer = ultimateAnswer;
}
}

Setter注入方式

基于Setter的注入方式是在Spring容器调用无參构造器或者无參静态工厂方法后,再调用bean中的setter方法实现的。

下面这个例子是一个通过纯setter方式注入的例子,这种方式在Java中非常常见,就是一个POJO,不依赖任何与容器相关的接口、类、注解。

public class SimpleMovieLister {

  // the SimpleMovieLister has a dependency on the MovieFinder
private MovieFinder movieFinder; // a setter method so that the Spring container can 'inject' a MovieFinder
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
} // business logic that actually 'uses' the injected MovieFinder is omitted...
}

依赖解析过程

Spring容器是这样解析依赖的:

  1. Spring容器通过配置元数据创建和初始化ApplicationContext,配置元数据可以使用Xml,Java代码或者注解描述。

  2. 每个bean的依赖形式都是由属性,构造器参数,静态工厂方法的参数(如果使用静态工厂方法替代构造器)来表述的,当bean被实例化的时候,提供给这个bean。

  3. 每个属性或者构造器的参数的值都需要去设置,或者是容器中某一bean的引用。

  4. 每个属性或构造器的参数的值都是从一种形式转换为属性或参数实际的类型。Spring默认可以将String类型转换为所有内置类型。比如int,long,String,boolean等。

Spring IOC(DI)之注入方式的更多相关文章

  1. spring ioc三种注入方式

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

  2. Spring IOC三种注入方式(接口注入、setter注入、构造器注入)(摘抄)

    IOC ,全称 (Inverse Of Control) ,中文意思为:控制反转, Spring 框架的核心基于控制反转原理. 什么是控制反转?控制反转是一种将组件依赖关系的创建和管理置于程序外部的技 ...

  3. Spring IOC 三种注入方式

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

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

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

  5. 关于Spring IOC (DI-依赖注入)需要知道的一切

    关联文章: 关于Spring IOC (DI-依赖注入)你需要知道的一切 关于 Spring AOP (AspectJ) 你该知晓的一切 <Spring入门经典>这本书无论对于初学者或者有 ...

  6. 关于Spring IOC (DI-依赖注入)

    <Spring入门经典>这本书无论对于初学者或者有经验的工程师还是很值一看的,最近花了点时间回顾了Spring的内容,在此顺带记录一下,本篇主要与spring IOC相关 ,这篇博文适合初 ...

  7. 关于Spring IOC (DI-依赖注入)你需要知道的一切

    <Spring入门经典>这本书无论对于初学者或者有经验的工程师还是很值一看的,最近花了点时间回顾了Spring的内容,在此顺带记录一下,本篇主要与spring IOC相关 ,这篇博文适合初 ...

  8. AutoFac IoC DI 依赖注入

    AutoFac IoC DI 依赖注入 记录点点滴滴知识,为了更好的服务后来者! 一.为什么使用AutoFac? 之前介绍了Unity和Ninject两个IOC容器,但是发现园子里用AutoFac的貌 ...

  9. spring四种依赖注入方式(转)

    spring四种依赖注入方式!! 平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提 ...

随机推荐

  1. SSL握手流程

    一.SSL是什么? 安全套接字(SSL)协议是Web浏览器和Web服务器之间安全交换信息的协议. SSL介于应用层和TCP层之间,应用层数据不再直接传递给传输层,而是传递给SSL层,SSL层对从应用层 ...

  2. Oracle不能导入空表解决方案

    C:\Users\Administrator>sqlplus / as sysdba SQL*Plus: Release 11.2.0.1.0 Production on 星期日 8月 17 1 ...

  3. 帝国cms本地搬家到服务器文章路径问题?

    由于我的服务器不支持采集功能,我只能选择先在本地采集好文章发布于本地,再打算同步于服务器. 按照官方的做法, 1.先进后台备份了网站的所有数据,系统——备份与恢复数据——备份数据 2.将e\admin ...

  4. haproxy 超时机制

    <pre name="code" class="python">option redispatch option redispatch 是否允许重新 ...

  5. 【蓝桥杯】入门训练 Fibonacci数列

      入门训练 Fibonacci数列   时间限制:1.0s   内存限制:256.0MB        问题描述 Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1. ...

  6. Parsing HTML with C++ (using Qt preferably) - Stack Overflow

    Parsing HTML with C++ (using Qt preferably) - Stack Overflow Parsing HTML with C++ (using Qt prefera ...

  7. MySql 初次安装登陆

    名称:随便写 服务器:127.0.0.1或者localhost 端口:在安装mysql应该看到是3306 用户:root 密码:(默认的是空,如果你设置过自己应该知道) 其他就可以不用设置

  8. 第五节 Code 128 码

    128码开始於1981年推出,是一种长度可变.连续性的字母数字条码.与其他一维条码比较起来,128码是较为复杂的条码系统,而其所能支援的字元也相对地比其他一维条码来得多,又有不同的编码方式可供交互运用 ...

  9. Netflix

    2009年Netflix举办了一场Netflix大奖赛.他们公开一批匿名数据,允许参赛团队使用以得出更好的算法.他们从获胜的团队中得到了现有算法10.06%的提升.Netflix本想再举行一场Netf ...

  10. vim Ctags 和taglist安装和使用

    Ctags是一个用于从程序源代码树产生索引文件(或tag文件),从而便于文本编辑器来实现快速定位的实用工具.在产生的tag文件中,每一个tag的入口指向了一个编程语言的对象.这个对象可以是变量定义.函 ...