Spring学习手册(6)—— bean生命周期管理我们学习了如何在IOC容器完成bean构造或销毁时添加指定操作动作。本篇我们将学习IOC容器的自动注入知识,通过自动注入可以极大的减少XML配置工作。
一、自动注入
Spring的IOC容器可以自动关联bean之间的依赖,我们将其称为自动注入。自动注入有以下优势:
- 自动注入可有效的减少构造器和属性参数设置;
- 自动注入可以根据对象的变化更改配置。如,需要向类添加依赖关系,可自动满足该依赖关系,而无需更改配置信息。
自动注入无法注入简单属性,如:基本类型(int、char、boolean等)、String类型和Class。
Spring为我们提供了以下四种自动注入方式:
模式 | 描述 |
---|---|
no | (默认)不进行自动注入,必须手动配置 |
byName | 依靠属性名称进行自动注入 |
byType | 按照属性类型进行自动注入,如果有两个一样的类型则抛出异常若不存在该类型则属性不进行注入 |
constructor | 与byType相似,若不存在构造器参数类型,将产生错误 |
Tip: 当使用byType时,若该属性类型在IOC容器中存在两个或两个以上的bean时,此时为了避免不可预测的情况的产生,Spring会抛出异常。
二、自动注入配置
2.1 自动注入开关
当我们想要某bean支持自动注入时,需要使用<bean>
标签中的autowire
属性,而值设为上表中的某项,默认为no。样式如下:
<bean id="autoWrieExample" class="com.example.AutoWireExample" autowire="byName"/>
public class AutoWireExample{
}
2.2全局配置
虽然只需要增加autowire
属性就可以免去为每个构造器参数或属性设置配置XML属性,但是若为每个bean增加该属性,也是一个不小的工作量。幸好,Spring为我们提供了全局的配置方式:default-autowire
。样式如下:
<beans default-autowire="byName">
......
</beans>
同样,当前<bean>
设置的自动注入值会覆盖全局设置的值。
Tip:一般情况下,我们多使用byName的方式来进行自动注入以避免出现按照类型自动注入可能导致的异常情况。
三、示例
该示例我们使用byName的自动注入方式,使用全局配置的方式使得IOC容器自动注入依赖关系。
public class Address {
private String street;
private String city;
public void setStreet(String street) {
this.street = street;
}
public void setCity(String city) {
this.city = city;
}
@Override
public String toString(){
return "Street: "+ street+" City: "+city;
}
}
public class Person {
private int age;
private String name;
private Address address;
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
public String toString(){
return "age: "+ age+" name: "+name+" address: "+address;
}
}
配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<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-4.3.xsd"
default-autowire="byType">
<bean id="address" class="com.liangwei.learnspring.Address">
<property name="street" value="NanJingRoad"/>
<property name="city" value="HangZhou"/>
</bean>
<bean id="person" class="com.liangwei.learnspring.Person" autowire="">
<property name="age" value="20"/>
<property name="name" value="Tom"/>
</bean>
</beans>
如上配置文件,我们可以看到id设置为person的bean并没有显示注入属性address的依赖关系,我们在beans标签里面设置了default-autowire
。同样我们也注意到,虽然我们开启了自动注入,但是关于age、name等简单类型属性我们依然需要配置注入关系。
public class Application {
public static void main(String[] args){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
Person person = applicationContext.getBean("person",Person.class);
System.out.println(person.toString());
}
}
运行上述代码,控制台得到如下输出信息:
age: 20 name: Tom address: Street: NanJingRoad City: HangZhou
从输出信息上我们可以看出,IOC容器自动将对address的依赖注入到了person内。
四、总结
本文我们一起学习了自动注入相关的知识,知识点相对简单,可以在本文给出的源代码的基础上使用不同的自动注入方式来体会其中的不同。另外,在平时的应用中一般使用byName方式较多。
本文源代码下载