接口有多个实现下,配置spring注入接口实现类默认注入的对象

接口有多个实现下,配置spring默认注入的对象
众所周知,spring可以向action中注入其需要的对象,一般的用法如下:
在配置文件中:
在对应的bookaction的调用中有一句:
private IBook iB
public void add()
x=iBook.addBook(book);
当时我看到就在想了,这个地方ibook又没有new,而且调用方法时候直接用的接口的对象(实际上已经是下面实现的对象了,用iBook.getclass就可以看得出来),假如我有两个implementation,它咋晓得调用哪一个?
后来写代码测试了,才知道,在加载spring容器的时候bookImpl对象就会被创建好,然后在action的时候,spring会直接把bookImpl对象注入到action类里面。
加入我初始化两个对象,
bookImpl2和bookImpl都是IBook
的实现,则spring在action的时候不知道放入哪一个,就会报以下错误:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'action.book.bookAction': Unsatisfied
dependency expressed through bean property 'iBook': : No unique
bean of type [service.interf.IBook] is defined: expected single
matching bean but found 2: [bookImpl, bookImpl2]; nested exception
is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No unique bean of type [service.interf.IBook] is defined: expected
single matching bean but found 2: [bookImpl, bookImpl2]
意思就是它不知道该放哪一个Ibook合适的实现到action中去。spring
注入的时候是依据类型作为判断的,当出现2个IBook类型的实现对象的时候,spring靠类型无法知道哪一个需要注入,所以会报错。
要解决这个问题,在spring3 可以这样做:
/t/568815/Spring/multiple-implementations-interface-default-implementation
http://static.springsource.org/spring/docs/3.0.0.M3/reference/html/ch04s11.html
如果要配置在xml文件中,需要用到&属性
http://www.blogjava.net/tianya0801/archive//182880.html
autowire的五种类型:
No autowiring is performed. All references to other beans must be
explicitly injected. This is the default mode.
Based on the name of a property, a matching bean name in the IoC
container will be injected into this property if it exists.
Based on the type of class on a setter, if only one instance of the
class exists in the IoC container it will be injected into this
property. If there is more than one instance of the class a fatal
exception is thrown.
constructor
Based on a constructor argument's class types, if only one instance
of the class exists in the IoC container it will be used in the
constructor.
autodetect
If there is a
valid constructor, the constructor autowiring mode will be chosen.
Otherwise if there is a default zero argument constructor the
byType autowiring mode will be chosen.
/book/in-depth-ioc-autowiring.html
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。18000人阅读
08 Spring(6)
Spring控制翻转中的依赖注入方式
依赖注入是指对象之间关系的控制权由应用代码中转到外部容器。Spring框架主要提供了Set注入和构造注入两种依赖注入方式。
&&1:Set注入指的就是在接受注入的类中定义一个要被注入的类型的一个set方法,并在参数中定义需要注入的元素。Set注入式一种装配Bean属性的直接方法,但Set注入的一个缺点就是它假设了所有的可变属性都可以通过set方法访问到,无法清晰地表示哪些属性是必须的,哪些属性是可选的。
& 2:构造注入是在接收注入的类中定义一个构造方法,并在构造方法中定义需要注入的参数。构造注入方式的优势是通过构造方法来强制依赖关系。
& 下面介绍一下两种方式的用法:
一:在Myeclipse中(笔者使用的是Myeclipse10版本)新建一个项目(java project或者web project都可)
二:右键项目 - MyEclipse - Add Spring Capabilities(添加Spring支持),选择3.0版本并添加引用核心类库,点击下一步。
& & & & & &
三:选择新创建一个spring bean 配置文件放到项目src目录下。
四:点击下一步,指定Hibernate 配置页,直接默认,点击完成即可。
五:新建类 HelloWorld.java
package com.xiami.
public class HelloWorld {
* 默认构造方法
public HelloWorld() {
* 用来进行构造注入的构造方法
* @param str
public HelloWorld(String str) {
this.str =
* 用来进行Set注入的方法
* @param str
public void setStr(String str) {
this.str =
* 输出字符串的方法
public void sayHello() {
System.out.println(str);
六:新建测试类Test.java
package com.xiami.
import org.springframework.beans.factory.BeanF
import org.springframework.beans.factory.xml.XmlBeanF
import org.springframework.core.io.ClassPathR
public class Test {
* @param args
public static void main(String[] args) {
// TODO Auto-generated method stub
//载入spring配置文件
BeanFactory bFactory = new XmlBeanFactory(new ClassPathResource(&applicationContext.xml&));
HelloWorld helloWorld = (HelloWorld) bFactory.getBean(&helloService&);
helloWorld.sayHello();
七:此时项目结构如下
八:打开applicationContext.xml文件,进行添加bean配置
以下是两种方式添加bean:
1:采用Set注入方式的Bean类的配置
右击applicationContext.xml的编辑界面 - Spring - new bean 打开Bean向导窗口,填写Bean Id(自定义命名和Test.java中getBean(&???&)对应。Bean class 选择要注入的HelloWorld类。点击Properties属性选项卡,给该bean新建一个属性。
九:在属性向导窗口填写 Name 对应HelloWorld.java中的属性名称,Spring Type 选择value,type选择String,Value 随便填值。
finish 既可。
十:保存applicationContext.xml, 添加bean后,配置文件多了红色标记的部分,读者可以运行Test.java。测试一下。发现hello world
字符串已经注入到了str变量上。
&?xml version=&1.0& encoding=&UTF-8&?&
xmlns=&http://www.springframework.org/schema/beans&
xmlns:xsi=&http://www.w3.org/2001/XMLSchema-instance&
xmlns:p=&http://www.springframework.org/schema/p&
xsi:schemaLocation=&http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd&&
&!-- 使用Set方式注入 --&
&span style=&color:#ff0000;&&&bean id=&helloService& class=&com.xiami.spring.HelloWorld&
abstract=&false& lazy-init=&default& autowire=&default&&
&property name=&str&&
&value type=&java.lang.String&&hello world&/value&
&/property&
&/bean&&/span&
&!-- 使用构造方法方式注入
&bean id=&helloService& class=&com.xiami.spring.HelloWorld&
abstract=&false& lazy-init=&default& autowire=&default&&
&constructor-arg&
&value type=&java.lang.String&&构造方法注入方式&/value&
&/constructor-arg&
2:采用构造注入方式的Bean类的配置
在以上Set方式的Bean Wizard(Bean 向导)窗口,不选择Properties选项卡,变为Constructor Args选项卡。并Add 新增一个构
造参数。Index和Java Class 不用填写。
十一:在增加构造方式bean的时候,之前第一个得先注释或者删除,不允许有多个id相同的bean。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1844163次
积分:15515
积分:15515
排名:第673名
原创:206篇
转载:212篇
评论:130条
(2)(2)(4)(1)(3)(1)(1)(2)(1)(3)(1)(6)(5)(1)(1)(2)(1)(1)(10)(11)(4)(15)(4)(6)(4)(6)(6)(1)(3)(2)(2)(3)(4)(8)(4)(5)(3)(1)(2)(3)(4)(5)(6)(10)(1)(16)(21)(31)(10)(38)(22)(58)(14)(37)Spring&IOC三种注入方式(接口注入、setter注入、构造器注入)(摘抄)
IOC ,全称 (Inverse Of Control) ,中文意思为:控制反转, Spring
框架的核心基于控制反转原理。
什么是控制反转?
控制反转是一种将组件依赖关系的创建和管理置于程序外部的技术。
由容器控制程序之间的关系,而不是由代码直接控制
由于控制权由代码转向了容器,所以称为反转
对象与对象之间的关系可以简单的理解为对象之间的依赖关系:
依赖关系:在 A 类需要类 B 的一个实例来进行某些操作,比如在类 A 的方法中需要调用类 B 的方法来完成功能,叫做 A 类依赖于
一个需要特定的依赖的组件一般会涉及一个依赖对象,在 IOC 的概念中叫做目标 (target) 。换句话说, IOC
提供了这样的服务,使一个组件能够在它的整个生命周期中访问它的依赖和服务,用这种方法与它的依赖进行交互。总的来说, IOC
能够被分解为两种子类型:依赖注入和依赖查找。
(1) 依赖查找
比如使用 JNDI 注册一个数据库连接池的示例中,代码中从注册处获得依赖关系的 JNDI 查找 (JNDI lookups)
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)
public class ClassA {
private InterfaceB clzB;
public void doSomething() {
Ojbect obj
=Class.forName(Config.BImplementation).newInstance();
clzB = (InterfaceB)
clzB.doIt()
上面的代码中, ClassA 依赖于 InterfaceB 的实现,如何获得 InterfaceB
实现类的实例?传统的方法是在代码中创建 InterfaceB 实现类的实例,并将起赋予 clzB 。
而这样一来, ClassA 在编译期即依赖于 InterfaceB
的实现。为了将调用者与实现者在编译期分离,于是有了上面的代码.
我们根据预先在配置文件中设定的实现类的类名 (Config.BImplementation) ,动态加载实现类,并通过
InterfaceB 强制转型后为 ClassA 所用。这就是接口注入的一个最原始的雏形。
而对于一个 Type1 型 IOC 容器而言,加载接口实现并创建其实例的工作由容器完成,见如下代码。
public class ClassA {
private InterfaceB clzB;
public Object doSomething(InterfaceB b) {
return clzB.doIt();
在运行期, InterfaceB 实例将由容器提供。
Type1 型 IOC 发展较早(有意或无意),在实际中得到了普遍应用,即使在 IOC
的概念尚未确立时,这样的方法也已经频繁出现在我们的代码中。
下面的代码大家应该非常熟悉:
public class MyServlet extends HttpServlet {
public void doGet(HttpServletRequest request,HttpServletResponse
response)throws ServletException, IOException { …… } }
这也是一个 Type1 型注入, HttpServletRequest 和 HttpServletResponse 实例由
Servlet Container 在运行期动态注入。
&2&Setter( 设值 ) 注入 (Type2)
各种类型的依赖注入模式中,设值注入模式在实际开发中得到了最广泛的应用。
public class ClassA {
private InterfaceB clzB;
public void setClzB(InterfaceB clzB) {
this. clzB = clzB; }
&3& 构造器注入 (Type3)
依赖关系是通过类构造函数建立的
容器通过调用类的构造方法将其所需的依赖关系注入其中
public class DIByConstructor { private final DataSource
public DIByConstructor(DataSource ds) {
this.dataSource =
&4& 三种依赖注入方式的比较
接口注入:
接口注入模式因为历史较为悠久,在很多容器中都已经得到应用。但由于其在灵活性、易用性上不如其他两种注入模式,因而在 IOC
的专题世界内并不被看好。
Setter 注入:
对于习惯了传统 javabean 开发的程序员,通过 setter 方法设定依赖关系更加直观。
如果依赖关系较为复杂,那么构造子注入模式的构造函数也会相当庞大,而此时设值注入模式则更为简洁。
如果用到了第三方类库,可能要求我们的组件提供一个默认的构造函数,此时构造子注入模式也不适用。
构造器注入:
在构造期间完成一个完整的、合法的对象。
所有依赖关系在构造函数中集中呈现。
依赖关系在构造时由容器一次性设定,组件被创建之后一直处于相对“不变”的稳定状态。
只有组件的创建者关心其内部依赖关系,对调用者而言,该依赖关系处于“黑盒”之中。
可见, Type3 和 Type2 模式各有千秋,而 Spring 、 PicoContainer 都对 Type3 和 Type2
类型的依赖注入机制提供了良好支持。这也就为我们提供了更多的选择余地。理论上,以 Type3 类型为主,辅之以 Type2
类型机制作为补充,可以达到最好的依赖注入效果,不过对于基于 Spring Framework 开发的应用而言, Type2
使用更加广泛。
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。本帖子已过去太久远了,不再提供回复功能。

我要回帖

更多关于 spring 接口注入 的文章

 

随机推荐