Spring IOC(DI)之注入方式
一次被问到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容器是这样解析依赖的:
Spring容器通过配置元数据创建和初始化
ApplicationContext,配置元数据可以使用Xml,Java代码或者注解描述。每个bean的依赖形式都是由属性,构造器参数,静态工厂方法的参数(如果使用静态工厂方法替代构造器)来表述的,当bean被实例化的时候,提供给这个bean。
每个属性或者构造器的参数的值都需要去设置,或者是容器中某一bean的引用。
每个属性或构造器的参数的值都是从一种形式转换为属性或参数实际的类型。Spring默认可以将String类型转换为所有内置类型。比如
int,long,String,boolean等。
Spring IOC(DI)之注入方式的更多相关文章
- spring ioc三种注入方式
spring ioc三种注入方式 IOC ,全称 (Inverse Of Control) ,中文意思为:控制反转 什么是控制反转? 控制反转是一种将组件依赖关系的创建和管理置于程序外部的技术. 由容 ...
- Spring IOC三种注入方式(接口注入、setter注入、构造器注入)(摘抄)
IOC ,全称 (Inverse Of Control) ,中文意思为:控制反转, Spring 框架的核心基于控制反转原理. 什么是控制反转?控制反转是一种将组件依赖关系的创建和管理置于程序外部的技 ...
- Spring IOC 三种注入方式
1. 接口注入 2. setter注入 3. 构造器注入 对象与对象之间的关系可以简单的理解为对象之间的依赖关系:A类需要B类的一个实例来进行某些操作,比如在A类的方法中需要调用B类 ...
- Spring IOC 三种注入方式(构造器,setter,接口)
Spring的依赖注入有三种方式: 1,构造器注入 2,setter注入 3,接口注入 下面我给大家介绍一下这三种注入 1.构造器注入 构造器注入主要是依赖于构造方法去实现,构造方法可以是有参也可以是 ...
- 关于Spring IOC (DI-依赖注入)需要知道的一切
关联文章: 关于Spring IOC (DI-依赖注入)你需要知道的一切 关于 Spring AOP (AspectJ) 你该知晓的一切 <Spring入门经典>这本书无论对于初学者或者有 ...
- 关于Spring IOC (DI-依赖注入)
<Spring入门经典>这本书无论对于初学者或者有经验的工程师还是很值一看的,最近花了点时间回顾了Spring的内容,在此顺带记录一下,本篇主要与spring IOC相关 ,这篇博文适合初 ...
- 关于Spring IOC (DI-依赖注入)你需要知道的一切
<Spring入门经典>这本书无论对于初学者或者有经验的工程师还是很值一看的,最近花了点时间回顾了Spring的内容,在此顺带记录一下,本篇主要与spring IOC相关 ,这篇博文适合初 ...
- AutoFac IoC DI 依赖注入
AutoFac IoC DI 依赖注入 记录点点滴滴知识,为了更好的服务后来者! 一.为什么使用AutoFac? 之前介绍了Unity和Ninject两个IOC容器,但是发现园子里用AutoFac的貌 ...
- spring四种依赖注入方式(转)
spring四种依赖注入方式!! 平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提 ...
随机推荐
- tomcat 会话超时设置
1.为单个WEB设置SESSION 在WEB.XML中添加 xml 代码 <session-config> <session-timeout>15</session-ti ...
- 17.1.1.9 Introducing Additional Slaves to an Existing Replication Environment 引入额外的Slaves 到一个存在的复制
17.1.1.9 Introducing Additional Slaves to an Existing Replication Environment 引入额外的Slaves 到一个存在的复制环境 ...
- JavaScript中cookie的路径(path)和域(domain)
cookie虽然是由一个网页所创建,但并不只是创建cookie的网页才能读 取该cookie.在默认情况下,与创建cookie的网页在同一目录或子目录下的所有网页都可以读取该cookie.但如果在这个 ...
- nodejs partials 分布视图
在学习<node.js开发指南>nodejs partials view时,怎么都不能运行成功.经过艰苦探索,终于成功了,分享一下. Cause: nodejs 的express 版本之间 ...
- JavaSE学习总结第02天_Java基础语法1
02.01 关键字的概述和使用 关键字概述:被Java语言赋予特定含义的单词 关键字特点:组成关键字的字母全部小写 关键字注意事项:goto和const作为保留字存在,目前并不使用,类似Notep ...
- html5之histroy浅析
history是HTML5的新特性,我们可以使用它操作这个历史记录堆栈. (1)history提供了对浏览器历史纪录堆栈的读取,同时实现在访问记录中的前进和后退: history.length 历史记 ...
- 用jmeter进行多用户并发压力测试 [转]
近日manager要求对项目进行压力测试,开始对jmeter进行了研究.jmeter是Apache一个开源项目,可对各种项目进行测试,甚至包括junit. 测试要求如下,多用户同时登陆web应用程序, ...
- Python学习之路——字符处理(一)
一.整数: 例如:1.10.30 整数可以做以下操作: bit_length函数:返回该整数占用的最少位数: >>> x=100 >>> x.bit_length( ...
- PowerShell入门(序):为什么需要PowerShell?
原文:http://www.cnblogs.com/ceachy/archive/2013/01/23/PowerShellPreface.html 曾几何时,微软的服务器操作系统因为缺乏一个强大的S ...
- Week15(12月16日):授课综述1
Part I:提问 =========================== 1.( )类提供了一个对Entity Framework的抽象,能够进行数据持久化并接受数据. A.Layout ...