注入常量是依赖注入中最简单的。配置方式以下所示:html
java代码:java
<property name="message" value="Hello World!"/> 数组
或 数据结构
<property name="index"><value>1</value></property><span class="Apple-style-span" style="font-size: 14px; white-space: normal; background-color: #ffffff;"> </span> ide
以上两种方式均可以,从配置来看第一种更简洁。注意此处“value”中指定的全是字符串,由Spring容器将此字符串转换成属性所须要的类型,若是转换出错,将抛出相应的异常。学习
Spring容器目前能对各类基本类型把配置的String参数转换为须要的类型。测试
注:Spring类型转换系统对于boolean类型进行了容错处理,除了能够使用“true/false”标准的Java值进行注入,还能使用“yes/no”、“on/off”、“1/0”来表明“真/假”,因此你们在学习或工做中遇到这种相似问题不要以为是人家配置错了,而是Spring容错作的很是好。this
java代码:spa
测试类
public class BooleanTestBean {
private boolean success;
public void setSuccess(boolean success) {
this.success = success;
}
public boolean isSuccess() {
return success;
}
}
配置文件(chapter3/booleanInject.xml)片断:
<!-- boolean参数值能够用on/off -->
<bean id="bean2" class="cn.javass.spring.chapter3.bean.BooleanTestBean">
<property name="success" value="on"/>
</bean>
<!-- boolean参数值能够用yes/no -->
<bean id="bean3" class="cn.javass.spring.chapter3.bean.BooleanTestBean">
<property name="success" value="yes"/>
</bean>
<!-- boolean参数值能够用1/0 -->
<bean id="bean4" class="cn.javass.spring.chapter3.bean.BooleanTestBean">
<property name="success" value="1"/>
</bean>
用于注入Bean的ID,ID是一个常量不是引用,且相似于注入常量,但提供错误验证功能,配置方式以下所示:
java代码:
<property name="id"><idref bean="bean1"/></property>
java代码:
<property name="id"><idref local="bean2"/></property>
两种方式均可以,上述配置本质上在运行时等于以下方式
java代码:
<bean id="bean1" class="……"/>
<bean id="idrefBean1" class="……">
<property name="id" value ="bean1"/>
</bean>
第二种方式(<idref bean="bean1"/>)能够在容器初始化时校验被引用的Bean是否存在,若是不存在将抛出异常,而第一种方式(<idref local="bean2"/>)只有在Bean实际使用时才能发现传入的Bean的ID是否正确,可能发生不可预料的错误。所以若是想注入Bean的ID,推荐使用第二种方式。
接下来学习一下如何使用吧:
首先定义测试Bean:
java代码:
package cn.javass.spring.chapter3.bean
public class IdRefTestBean {
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
其次定义配置文件(chapter3/idRefInject.xml):
java代码:
<bean id="bean1" class="java.lang.String">
<constructor-arg index="0" value="test"/>
</bean>
<bean id="bean2" class="java.lang.String">
<constructor-arg index="0" value="test"/>
</bean>
java代码:
<bean id="idrefBean1" class="cn.javass.spring.chapter3.bean.IdRefTestBean">
<property name="id"><idref bean="bean1"/></property>
</bean>
<bean id="idrefBean2" class="cn.javass.spring.chapter3.bean.IdRefTestBean">
<property name="id"><idref local="bean2"/></property>
</bean>
从配置中能够看出,注入的Bean的ID是一个java.lang.String类型,即字符串类型,所以注入的一样是常量,只是具备校验功能。
<idref bean="……"/>将在容器初始化时校验注入的ID对于的Bean是否存在,若是不存在将抛出异常。
<idref local="……"/>将在XML解析时校验注入的ID对于的Bean在当前配置文件中是否存在,若是不存在将抛出异常,它不一样于<idref bean="……"/>,<idref local="……"/>是校验发生在XML解析式而非容器初始化时,且只检查当前配置文件中是否存在相应的Bean。
Spring不只能注入简单类型数据,还能注入集合(Collection、无序集合Set、有序集合List)类型、数组(Array)类型、字典(Map)类型数据、Properties类型数据,接下来就让咱们一个个看看如何注入这些数据类型的数据。
1、注入集合类型:包括Collection类型、Set类型、List类型数据:
(1)List类型:须要使用<list>标签来配置注入,其具体配置以下:
让咱们来写个测试来练习一下吧:
准备测试类:
java代码:
package cn.javass.spring.chapter3.bean;
import java.util.List;
public class ListTestBean {
private List<String> values;
public List<String> getValues() {
return values;
}
public void setValues(List<String> values) {
this.values = values;
}
}
进行Bean定义,在配置文件(resources/chapter3/listInject.xml)中配置list注入:
java代码:
<bean id="listBean" class="cn.javass.spring.chapter3.bean.ListTestBean">
<property name="values">
<list>
<value>1</value>
<value>2</value>
<value>3</value>
</list>
</property>
</bean>
测试代码:
java代码:
public void testListInject() {
BeanFactory beanFactory =
new ClassPathXmlApplicationContext("chapter3/listInject.xml");
ListTestBean listBean = beanFactory.getBean("listBean", ListTestBean.class);
System.out.println(listBean.getValues().size());
Assert.assertEquals(3, listBean.getValues().size());
}
(2)Set类型:须要使用<set>标签来配置注入,其配置参数及含义和<lsit>标签彻底同样,在此就不阐述了:
准备测试类:
java代码:
package cn.javass.spring.chapter3.bean;
import java.util.Collection;
public class CollectionTestBean {
private Collection<String> values;
public void setValues(Collection<String> values) {
this.values = values;
}
public Collection<String> getValues() {
return values;
}
}
进行Bean定义,在配置文件(resources/chapter3/listInject.xml)中配置list注入:
java代码:
<bean id="setBean" class="cn.javass.spring.chapter3.bean.SetTestBean">
<property name="values">
<set>
<value>1</value>
<value>2</value>
<value>3</value>
</set>
</property>
</bean>
具体测试代码就不写了,和listBean测试代码彻底同样。
(2)Collection类型:由于Collection类型是Set和List类型的基类型,因此使用<set>或<list>标签均可以进行注入,配置方式彻底和以上配置方式同样,只是将测试类属性改为“Collection”类型,若是配置有问题,可参考cn.javass.spring.chapter3.DependencyInjectTest测试类中的testCollectionInject测试方法中的代码。
2、注入数组类型:须要使用<array>标签来配置注入,其中标签属性“value-type”和“merge”和<list>标签含义彻底同样,具体配置以下:
若是练习时遇到配置问题,能够参考“cn.javass.spring.chapter3.DependencyInjectTest”测试类中的testArrayInject测试方法中的代码。
3、注入字典(Map)类型:字典类型是包含键值对数据的数据结构,须要使用<map>标签来配置注入,其属性“key-type”和“value-type”分别指定“键”和“值”的数据类型,其含义和<list>标签的“value-type”含义同样,在此就不罗嗦了,并使用<key>子标签来指定键数据,<value>子标签来指定键对应的值数据,具体配置以下:
若是练习时遇到配置问题,能够参考“cn.javass.spring.chapter3.DependencyInjectTest”测试类中的testMapInject测试方法中的代码。
4、Properties注入:Spring能注入java.util.Properties类型数据,须要使用<props>标签来配置注入,键和值类型必须是String,不能变,子标签<prop key=”键”>值</prop>来指定键值对,具体配置以下:
若是练习时遇到配置问题,能够参考cn.javass.spring.chapter3.DependencyInjectTest测试类中的testPropertiesInject测试方法中的代码。
到此咱们已经把简单类型及集合类型介绍完了,你们可能会问怎么没见注入“Bean之间关系”的例子呢?接下来就让咱们来说解配置Bean之间依赖关系,也就是注入依赖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、构造器注入方式:
(1)经过” <constructor-arg>”标签的ref属性来引用其余Bean,这是最简化的配置:
(2)经过” <constructor-arg>”标签的子<ref>标签来引用其余Bean,使用bean属性来指定引用的Bean:
2、setter注入方式:
(1)经过” <property>”标签的ref属性来引用其余Bean,这是最简化的配置:
(2)经过” <property>”标签的子<ref>标签来引用其余Bean,使用bean属性来指定引用的Bean:
3、接下来让咱们用个具体例子来说解一下具体使用吧:
(1)首先让咱们定义测试引用Bean的类,在此咱们能够使用原有的HelloApi实现,而后再定义一个装饰器来引用其余Bean,具体装饰类以下:
java代码:
package cn.javass.spring.chapter3.bean;
import cn.javass.spring.chapter2.helloworld.HelloApi;
public class HelloApiDecorator implements HelloApi {
private HelloApi helloApi;
//空参构造器
public HelloApiDecorator() {
}
//有参构造器
public HelloApiDecorator(HelloApi helloApi) {
this.helloApi = helloApi;
}
public void setHelloApi(HelloApi helloApi) {
this.helloApi = helloApi;
}
@Override
public void sayHello() {
System.out.println("==========装饰一下===========");
helloApi.sayHello();
System.out.println("==========装饰一下===========");
}
}
(2)定义好了测试引用Bean接下来该在配置文件(resources/chapter3/beanInject.xml)进行配置Bean定义了,在此将演示经过构造器及setter方法方式注入依赖Bean:
java代码:
<!-- 定义依赖Bean -->
<bean id="helloApi" class="cn.javass.spring.chapter2.helloworld.HelloImpl"/>
<!-- 经过构造器注入 -->
<bean id="bean1" class="cn.javass.spring.chapter3.bean.HelloApiDecorator">
<constructor-arg index="0" ref="helloApi"/>
</bean>
<!-- 经过构造器注入 -->
<bean id="bean2" class="cn.javass.spring.chapter3.bean.HelloApiDecorator">
<property name="helloApi"><ref bean=" helloApi"/></property>
</bean>
(3)测试一下吧,测试代码(cn.javass.spring.chapter3.DependencyInjectTest)片断以下:
java代码:
public void testBeanInject() {
BeanFactory beanFactory =
new ClassPathXmlApplicationContext("chapter3/beanInject.xml");
//经过构造器方式注入
HelloApi bean1 = beanFactory.getBean("bean1", HelloApi.class);
bean1.sayHello();
//经过setter方式注入
HelloApi bean2 = beanFactory.getBean("bean2", HelloApi.class);
bean2.sayHello();
}