前边IoC一章我们已经了解了Bean依赖容器,那容器如何注入Bean的依赖资源,
Spring IoC容器注入依赖资源主要有以下两种基本实现方式:
-
构造器注入:就是容器实例化Bean时注入那些依赖,通过在在Bean定义中指定构造器参数进行注入依赖,包括实例工厂方法参数注入依赖,但静态工厂方法参数不允许注入依赖;
-
setter注入:通过setter方法进行注入依赖;
-
方法注入:能通过配置方式替换掉Bean方法,也就是通过配置改变Bean方法 功能。
构造器注入
构造器注入可以根据参数索引注入、参数类型注入或Spring3支持的参数名注入。
使用构造器注入通过配置构造器参数实现,构造器参数就是依赖。除了构造器方式,还有静态工厂、实例工厂方法 可以进行构造器注入。
构造器注入 实现接口实例化(依赖注入实例化)与传统实例化的区别*:
可以根据 索引,参数类型,参数名字 三种方式注入
____________________________________________________________________________
实例
让我们来用具体的例子来看一下构造器注入怎么使用吧。
(1)首先准备Bean类,在此我们就使用“HelloImpl3”这个类。(Bean类)
(2)有了Bean类,接下来要进行Bean定义配置,我们需要配置三个Bean来完成上述三种依赖注入测试,其中Bean ”byIndex”是通过索引注入依赖;Bean ”byType”是根据类型进行注入依赖;Bean ”byName”是根据参数名字进行注入依赖,具体配置文件(constructorDependencyInject.xml)如下:
构造器注入
静态工厂方法注入和实例工厂注入
测试代码和构造器方式完全一样,只是配置文件不一样,大家只需把测试文件改一下就可以了。还有一点需 要大家注意就是静态工厂方式和实例工厂方式根据参数名字注入的方式只支持通过在class文件中添加“变量调试信息” 方式才能运行,ConstructorProperties注解方式不能工作,它只对构造器方式起作用,不建议使用根据参数名进行构 造器注入。
____________________________________________________________________________
setter注入**
在通过构造器、静态工厂或实例工厂实例好Bean后,
通过调用Bean类的setter方法进行注入依赖,
(property name=“ ” value=“ ” )的形式
setter注入方式:
setter注入方式只有一种根据setter名字进行注入:
实例
(2)配置Bean定义,具体配置文件(setterDependencyInject.xml)片段如下:
知道如何配置了,但Spring如何知道setter方法?如何将值注入进去的呢?
其实方法名是要遵守约定的,setter注 入的方法名要遵循“JavaBean getter/setter 方法命名约定”:
JavaBean:是本质就是一个POJO类,但具有一下限制:
-
该类必须要有公共的无参构造器,如public HelloImpl4() {};
-
属性为private访问级别,不建议public,如private String message;
-
属性必要时通过一组setter(修改器)和getter(访问器)方法来访问;
-
setter方法,以“set” 开头,后跟首字母大写的属性名,如“setMesssage”,简单属性一般只有一个方法参 数,方法返回值通常为“void”;
-
getter方法,一般属性以“get”开头,对于boolean类型一般以“is”开头,后跟首字母大写的属性名,如 “getMesssage”,“isOk”;
___________________________________________________________________________
注入常量
注入常量是依赖注入中最简单的。配置方式如下所示:
以上两种方式都可以,从配置来看第一种更简洁。注意此处“value”中指定的全是字符串,由Spring容器将此字 符串转换成属性所需要的类型,如果转换出错,将抛出相应的异常。
Spring容器目前能对各种基本类型把配置的String参数转换为需要的类型。
注:Spring类型转换系统对于boolean类型进行了容错处理,除了可以使用“true/false”标准的Java值进行注入,还 能使用“yes/no”、“on/off”、“1/0”来代表“真/假”,所以大家在学习或工作中遇到这种类似问题不要觉得是人 家配置错了,而是Spring容错做的非常好
注入集合、数组和字典
Spring不仅能注入简单类型数据,还能注入集合(Collection、无序集合Set、有序集合List)类型、数组(Array)类 型、字典(Map)类型数据、Properties类型数据,接下来就让我们一个个看看如何注入这些数据类型的数据。
一、注入集合类型:包括Collection类型、Set类型、List类型数据:
(1)List类型:需要使用<list>标签来配置注入,其具体配置如下:
测试:
(2)Set类型:需要使用<set>标签来配置注入,其配置参数及含义和<lsit>标签完全一样,在此就不阐述了:
二、注入数组类型:需要使用<array>标签来配置注入,其中标签属性“value-type”和“merge”和<list>标签含义 完全一样,具体配置如下:
三、注入字典(Map)类型:字典类型是包含键值对数据的数据结构,需要使用<map>标签来配置注入,其属性 “key-type”和“value-type”分别指定“键”和“值”的数据类型,其含义和<list>标签的“value-type”含义一 样,在此就不罗嗦了,并使用<key>子标签来指定键数据,<value>子标签来指定键对应的值数据,具体配置如下:
___________________________________________________________________________
引用其它Bean
上边章节已经介绍了注入常量、集合等基本数据类型和集合数据类型,本小节将介绍注入依赖Bean及注入内部 Bean。
引用其他Bean的步骤与注入常量的步骤一样,可以通过构造器注入及setter注入引用其他Bean,只是引用其他 Bean的注入配置稍微变化了一下:
可以将“<constructor-arg index="0" value="Hello World!"/>”和“<property name="message" value="Hello World!"/>”中的value属性替换成bean属性,其中bean属性指定配置文件中的其 他Bean的id或别名。另一种是把<value>标签替换为<.ref bean=”beanName”>,bean属性也是指定配置文件中的 其他Bean的id或别名。那让我们看一下具体配置吧:
一、构造器注入方式:
(1)通过” <constructor-arg>”标签的ref属性来引用其他Bean,这是最简化的配置:(此方法简单)
(2)通过” <constructor-arg>”标签的子<ref>标签来引用其他Bean,使用bean属性来指定引用的Bean:
二、setter注入方式:
____________________________________________________________________________
配置简写
让我们来总结一下依赖注入配置及简写形式,其实我们已经在以上部分穿插着进行简化配置了:
一、构造器注入:
1)常量值
简写:<constructor-arg index="0" value="常量"/>
全写:<constructor-arg index="0"><value>常量</value></constructor-arg>
2)引用
简写:<constructor-arg index="0" ref="引用"/>
全写:<constructor-arg index="0"><ref bean="引用"/></constructor-arg>
二、setter注入:
1)常量值
简写:<property name="message" value="常量"/>
全写:<property name="message"><value>常量</value></ property>
2)引用
简写:<property name="message" ref="引用"/>
全写:<property name="message"><ref bean="引用"/></ property>
3)数组:<array>没有简写形式
4)列表:<list>没有简写形式
5)集合:<set>没有简写形式
6)字典
简写:<map>
<entry key="键常量" value="值常量"/>
<entry key-ref="键引用" value-ref="值引用"/>
</map>
全写:<map>
<entry><key><value>键常量</value></key><value>值常量</value></entry>
<entry><key><ref bean="键引用"/></key><ref bean="值引用"/></entry>
</map>
7)Properties:没有简写形式
三、使用p命名空间简化setter注入:
使用p命名空间来简化setter注入,具体使用如下:
• xmlns:p="http://www.springframework.org/schema/p" :首先指定p命名空间;
• <bean id="……" class="……" p:id="value"/> :常量setter注入方式,其等价于<property name="id" value="value"/>;
▪ <bean id="……" class="……" p:id-ref="bean1"/> :引用setter注入方式,其等价于<property name="id" ref="bean1"/>。