一次被问到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. WINDOWS硬件通知应用程序的常方法

    摘要:在目前流行的Windows操作系统中,设备驱动程序是操纵硬件的最底层软件接口.为了共享在设备驱动程序设计过程中的经验,给出设备驱动程序通知应用程序的5种方法,详细说明每种方法的原理和实现过程,并 ...

  2. linux64位系统中g++4.4.7下使用wcsncpy函数有造成段错误的BUG(其它g++版本号未知)

    一.描写叙述 眼下已经linux64位系统中g++4.4.7下发现了该bug.其它的版本号还未測试. 经測试,假设传入wcsncpy函数第一个參数(即目标缓冲区)的地址不能被4整除的话就必然会发生段错 ...

  3. HDU4712+随机算法

    随机算法 求n个20位的2进制串的MinDist. Dist:两个串的异或结果中1的个数 /* 随机算法 */ #include<algorithm> #include<iostre ...

  4. 浅谈CSS布局

    在No.4中谈及了下盒子模型,引出布局模型 1.布局模型有三类: 1)流动模型  flow(默认) 2)浮动模型  float 3)层模型  layer 2.文档流 :指的是文本沿着从左到右的方向展开 ...

  5. for语句的嵌套(示例及练习)

    for(初始条件:循环条件:状态改变) {for(初始条件:循环条件:状态改变) {     循环体      }} 一般,用来解决循环的方法:穷举法.迭代法. 示例一:阶乘的和 示例二: 练习一:兔 ...

  6. python之filter过滤器

    Python内建的filter()函数用于过滤序列. 和map()类似,filter()也接收一个函数和一个序列.和map()不同的时,filter()把传入的函数依次作用于每个元素,然后根据返回值是 ...

  7. 如何隐藏DLL中,导出函数的名称?

    一.引言 很多时候,我们写了一个Dll,不希望别人通过DLL查看工具,看到我们的导出函数名称.可以通过以下步骤实现: 1. 在def函数中做如下定义: LIBRARY EXPORTS HideFunc ...

  8. myeclipse 8.6 插件安装之SVN

    在这里我要说明一点,myEclipse 8.6的插件安装和之前的版本可能会有一些区别,下面是SVN插件的安装: 1.从官网下载site-1.6.13.zip文件,网址是:subclipse.tigri ...

  9. JS 某一区域内所有CheckBox全选和取消全选(.net)

    假设在某个table中的两个td,一个放全选checkbox,一个放所有的checkbox[其他标签类似] eg:        <td>人才类别:<asp:CheckBox ID= ...

  10. NET Core 环境搭建和命令行CLI入门

    NET Core 环境搭建和命令行CLI入门 2016年6月27日.NET Core & ASP.NET Core 1.0在Redhat峰会上正式发布,社区里涌现了很多文章,我也计划写个系列文 ...