Spring重温(三)--Spring依赖注入(DI)
前言:在Spring框架中,DI(依赖注入)是用来定义对象彼此间的依赖,主要有set方法注入和构造器注入两种方式。另外,当一个类包含多个构造函数带的参数相同,它总是会造成构造函数注入参数类型歧义的问题,我会在第3点进行介绍并给出解决方案。
1.setter方法注入:
package com.yiibai.output; import com.yiibai.output.IOutputGenerator; public class OutputHelper
{
IOutputGenerator outputGenerator; public void setOutputGenerator(IOutputGenerator outputGenerator){
this.outputGenerator = outputGenerator;
} }
一个 bean 配置文件用来声明bean 和通过 setter 设置注入(property标签)的依赖。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="OutputHelper" class="com.yiibai.output.OutputHelper">
<property name="outputGenerator">
<ref bean="CsvOutputGenerator" />
</property>
</bean> <bean id="CsvOutputGenerator" class="com.yiibai.output.impl.CsvOutputGenerator" />
</beans>
2.构造器注入:
例子:
package com.yiibai.output; import com.yiibai.output.IOutputGenerator; public class OutputHelper
{
IOutputGenerator outputGenerator; OutputHelper(IOutputGenerator outputGenerator){
this.outputGenerator = outputGenerator;
}
}
bean 配置文件来声明bean并通过构造函数(constructor-arg标签)设置注入依赖
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="OutputHelper" class="com.yiibai.output.OutputHelper">
<constructor-arg>
<bean class="com.yiibai.output.impl.CsvOutputGenerator" />
</constructor-arg>
</bean> <bean id="CsvOutputGenerator" class="com.yiibai.output.impl.CsvOutputGenerator" /> </beans>
3.当一个类包含多个构造函数带的参数相同,它总是会造成构造函数注入参数类型歧义的问题。
让我们来看看这个客户 bean 实例。它包含两个构造方法,均接受3个不同的数据类型参数:
package com.yiibai.common; public class Customer
{
private String name;
private String address;
private int age; public Customer(String name, String address, int age) {
this.name = name;
this.address = address;
this.age = age;
} public Customer(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
//getter and setter methods
public String toString(){
return " name : " +name + "\n address : "
+ address + "\n age : " + age;
} }
在Spring bean 的配置文件中,我们传递一个“yiibai' 的名字,地址为'188',以及年龄为'28'。
<!--Spring-Customer.xml-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="CustomerBean" class="com.yiibai.common.Customer"> <constructor-arg>
<value>yiibai</value>
</constructor-arg> <constructor-arg>
<value>188</value>
</constructor-arg> <constructor-arg>
<value>28</value>
</constructor-arg>
</bean> </beans>
运行它,你期望的结果是什么?
package com.yiibai.common; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class App
{
public static void main( String[] args )
{
ApplicationContext context =
new ClassPathXmlApplicationContext(new String[] {"Spring-Customer.xml"}); Customer cust = (Customer)context.getBean("CustomerBean");
System.out.println(cust);
}
}
输出结果:
name : yiibai
address : 28
age : 188
其结果不是我们所期望的,第一个构造器不执行,而是第二构造函数运行。在Spring参数类型'188' 能够转换成int,所以Spring只是转换它,并采用第二个构造来执行,即使你认为它应该是一个字符串。
constructor arguments specified but no matching constructor
found in bean 'CustomerBean' (hint: specify index and/or
type arguments for simple parameters to avoid type ambiguities
为了解决这个问题,应该为构造函数指定的确切数据类型,通过像这样类型的属性:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="CustomerBean" class="com.yiibai.common.Customer"> <constructor-arg type="java.lang.String">
<value>yiibai</value>
</constructor-arg> <constructor-arg type="java.lang.String">
<value>188</value>
</constructor-arg> <constructor-arg type="int">
<value>28</value>
</constructor-arg> </bean> </beans>
再次运行它,现在得到你所期望的:
name : yiibai
address : 188
age
总结:在依赖注入中,主要有seter方法注入和构造函数注入两种方式,其中setter方法注入是在xml配置文件中通过property设置依赖,而构造器通过constructor-arg设置依赖;
显式声明每个构造函数参数的数据类型,可以避免上述构造注入型歧义的问题。
Spring重温(三)--Spring依赖注入(DI)的更多相关文章
- Spring第一课:依赖注入DI(二)
DI Dependency Injection ,依赖注入 is a :是一个,继承. has a:有一个,成员变量,依赖. class B { private A a; //B类依赖A类 } 依 ...
- Spring自动装配之依赖注入(DI)
依赖注入发生的时间 当Spring IOC 容器完成了Bean 定义资源的定位.载入和解析注册以后,IOC 容器中已经管理类Bean定义的相关数据,但是此时IOC 容器还没有对所管理的Bean 进行依 ...
- spring(3)------控制反转(IOC)/依赖注入(DI)
一.spring核心概念理解 控制反转: 控制反转即IoC (Inversion of Control).它把传统上由程序代码直接操控的对象的调用权交给容器.通过容器来实现对象组件的装配和管理. 所谓 ...
- 【SSH系列】深入浅出spring IOC中三种依赖注入方式
spring的核心思想是IOC和AOP,IOC-控制反转,是一个重要的面向对象编程的法则来消减计算机程序的耦合问题,控制反转一般分为两种类型,依赖注入和依赖查找,依赖什么?为什么需要依赖?注入什么?控 ...
- 回客科技 面试的 实现ioc 容器用到的技术,简述BeanFactory的实现原理,大搜车面试的 spring 怎么实现的依赖注入(DI)
前言:这几天的面试,感觉自己对spring 的整个掌握还是很薄弱.所以需要继续加强. 这里说明一下spring的这几个面试题,但是实际的感觉还是不对的,这种问题我认为需要真正读了spring的源码后说 ...
- spring IOC中三种依赖注入方式
Spring的核心思想是IOC和AOP,IOC-控制反转,是一个重要的面向对象编程的法则,用来消减计算机程序之间的耦合问题,控制反转一般分为两种类型,依赖注入和依赖查找,依赖什么?为什么需要依赖?注入 ...
- 深入浅出spring IOC中三种依赖注入方式
深入浅出spring IOC中三种依赖注入方式 spring的核心思想是IOC和AOP,IOC-控制反转,是一个重要的面向对象编程的法则来消减计算机程序的耦合问题,控制反转一般分为两种类型,依赖注入和 ...
- Spring框架学习笔记(1)——控制反转IOC与依赖注入DI
Spring框架的主要作用,就是提供了一个容器,使用该容器就可以创建并管理对象.比如说Dao类等,又或者是具有多依赖关系的类(Student类中包含有Teacher类的成员变量) Spring有两个核 ...
- 【学习笔记】 使用XML配置和注解实现Spring的依赖注入DI (2-3-2)
Spring的四个核心组件 1.beans Bean是包装应用程序自定义对象Object的 Object中保存数据 2.core 3.context 一个Bean的关系集合 4.expression ...
随机推荐
- windows下ngnix+php配置
1.需要工具: 下载ngnix 网址:http://nginx.org/ 下载:RunHiddenConsole 第二步 将下载文件解压后,将RunHiddenConsole拷贝到ngnix目录与p ...
- linux基本
一.初识 Linux与windows相比的优点是:长期稳定的运行,避免了因为系统的问题导致的项目运行中断:占用资源少:开源软件多. Centos(Community Enterprise Operat ...
- python之三元表达式、列表推导、生成器表达式、递归、匿名函数、内置函数
目录 一 三元表达式 二 列表推到 三 生成器表达式 四 递归 五 匿名函数 六 内置函数 一.三元表达式 def max(x,y): return x if x>y else y print( ...
- opencv源码学习: getStructuringElement函数;
getStructuringElement函数归属于形态学,可以建立指定大小.形状的结构: 原型: /** @brief Returns a structuring element of the sp ...
- python自动化开发-[第十二天]-前端Css
CSS基本语法 CSS 规则由两个主要的部分构成:选择器,以及一条或多条声明. selector { property: value; property: value; ... property: v ...
- angular 中自己常用的下拉框获取值方法
方法一 HTML页中 <select name="" id="if02" data-first-option="true" (chan ...
- 《Go并发编程实战》读书笔记-初识Go语言
<Go并发编程实战>读书笔记-初识Go语言 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在讲解怎样用Go语言之前,我们先介绍Go语言的特性,基础概念和标准命令. 一. ...
- python django基础二URL路由系统
URL配置 基本格式 from django.conf.urls import url #循环urlpatterns,找到对应的函数执行,匹配上一个路径就找到对应的函数执行,就不再往下循环了,并给函数 ...
- C#设计模式(14)——模板方法模式
1.模板方法模式介绍 提到模板我们经常会想到简历模板/PPT模板等,以简历模板为例,不同的人可以使用一样的简历模板,在填充内容时根据自己的名字/工作经历等填写自己的内容,从而形成不同的简历.在OO中模 ...
- hibernate状态转换关系图【原】
hibernate状态转换 其它参考 简单理解Hibernate三种状态的概念及互相转化 简单的Hibernate入门介绍