目录
一、介绍
1.1 手动装配
二、自动装配
2.1通过XML文件
2.1.1 byName根据属性名称自动注入?
2.1.2? byType根据属性类型自动注入
2.2 通过注解实现
准备工作
2.2.1 @Autowired
2.2.2 @Qualifier注解
2.2.3 @Resource注解
2.2.4 @Autowired与@Resource异同
结语
一、介绍
自动装配:根据指定装配规则(属性名称或者属性类型),Spring自动将匹配的属性值进行注入。
简单来讲就是:Spring会在上下文中自动查找,并自动给bean装配与其关联的属性。
Spring中实现自动装配的方式:
(1)通过XML文件。
(2)通过注解。
既然有自动装配,就说明有手动装配,什么是手动装配呢?下面用一个例子来解释:
1.1 手动装配
实体类Book:
public class Book {
private int id;
private String name;
//get,set,有参构造,无参构造
}
实体类Teacher:
public class Teacher {
private int id;
private String name;
//get,set,有参构造,无参构造
}
实体类:Student
public class Student {
private String name;
private Teacher teacher;
private Book book;
//get,set,有参构造,无参构造
}
XML配置:
<bean id="book" class="com.yixin.dao.Book">
<property name="name" value="Java编程思想"/>
<property name="id" value="1"/>
</bean>
<bean id="teacher" class="com.yixin.dao.Teacher">
<property name="name" value="王老师"/>
<property name="id" value="1"/>
</bean>
<bean id="student" class="com.yixin.dao.Student">
<property name="name" value="一心"/>
<property name="book" ref="book"/>
<property name="teacher" ref="teacher"/>
</bean>
可以看到,我们配置Student这个Bean时,是需要我们手动地将Book和Teacher进行装配进去的,这种方式就是手动装配。
二、自动装配
接下来开始讲自动装配
2.1通过XML文件
其种类有: (1)byName根据属性名称自动注入? (2)? ?byType根据属性类型自动注入
2.1.1 byName根据属性名称自动注入?
<bean id="book" class="com.yixin.dao.Book">
<property name="name" value="Java编程思想"/>
<property name="id" value="1"/>
</bean>
<bean id="teacher" class="com.yixin.dao.Teacher">
<property name="name" value="王老师"/>
<property name="id" value="1"/>
</bean>
<bean id="student" class="com.yixin.dao.Student" autowire="byName">
<property name="name" value="一心"/>
</bean>
注意看student,这时并不需要进行手动装配Book和Teacher了。
实现机制:
第一步:Spring会根据class属性找到实体类
第二步:查询实体类中所有set方法的名字
第三步:根据set方法后面的名字,首字母小写(如setBook(),那其后面名字为book)
第四步: 根据这个名字,再到配置文件中寻找一个与该名字相同id的Bean,注入进来。
也就是说如果在配置文件中查找不到你的set方法后面的名字并且没有相应的类型(唯一),那么就无法完成注入。
2.1.2? byType根据属性类型自动注入
XML配置文件:
<bean id="A" class="com.yixin.dao.Book">
<property name="name" value="Java编程思想"/>
<property name="id" value="1"/>
</bean>
<bean id="B" class="com.yixin.dao.Teacher">
<property name="name" value="王老师"/>
<property name="id" value="1"/>
</bean>
<bean id="student" class="com.yixin.dao.Student" autowire="byType">
<property name="name" value="一心"/>
</bean>
注意:
(1)根据需要注入的属性的类型来完成对属性的注入,并不对bean的id作要求
(2)同一类型的对象,在spring容器中唯一。如果不唯一,会报不唯一的异常,因为其是根据类型来注入的,多个相同类型Spring就不知道需要注入哪一个了。
2.2 通过注解实现
注解是通过反射来实现的。
准备工作
(1)在spring配置文件中引入context文件头
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
(2)开启属性注解支持
必须要写在xml中,这是用来开启注解的支持,如果不加上注解就无效。
<context:annotation-config/>
2.2.1 @Autowired
XML文件
<bean id="book" class="com.yixin.dao.Book">
<property name="name" value="Java编程思想"/>
<property name="id" value="1"/>
</bean>
<bean id="teacher" class="com.yixin.dao.Teacher">
<property name="name" value="王老师"/>
<property name="id" value="1"/>
</bean>
<bean id="student" class="com.yixin.dao.Student" >
<property name="name" value="一心"/>
</bean>
注解实现
public class Student {
private String name;
@Autowired
private Teacher teacher;
@Autowired
private Book book;
//set,get,有参构造,无参构造
}
在实体类的对应属性上添加@Autowired注解(也可以把注解放到对应属性的set方法上)
注解方法装配属性过程:
(1)spring会默认优先根据(被注解修饰的)属性类型去容器中找对应的组件(bean),找到就赋值;
(2)若找到多个相同类型的组件,再将属性的名称作为组件(bean)的id去容器中查找。
扩展:
@Autowired(required=false) ?说明:
false:对象可以为null;等于告诉 Spring:在找不到匹配 Bean 时也不报错。
true:对象必须存对象,不能为null。
注意:当不能确定 Spring 容器中一定拥有某个类的 Bean 时,可以在需要自动注入该类 Bean 的地方可以使用@Autowired(required=?false)。这等于告诉 Spring:在找不到匹配 Bean 时也不报错。
2.2.2 @Qualifier注解
注意:不可以单独使用
可以和使用Autowired搭配使用:@Qualifier指定需要装配的组件的id,而不是使用属性名。
如下,spring就会优先在容器中查找id为bean1的组件。
public class Student {
private String name;
@Autowired
@Qualifier("bean1")
private Teacher teacher;
@Autowired
private Book book;
//set,get,有参构造,无参构造
}
使用@Qualifier注解的情况: 当IOC容器根据属性类型去容器中找找到多个相同类型的组件,再将属性的名称作为组件(bean)的id去容器中查找找不到时就是用这两个注解搭配,指定需要装配的bean的id。 ?
2.2.3 @Resource注解
执行过程:
(1)@Resource如有指定的name属性,先按name进行配置文件Bean查找装配;
(2)没有指定name,则用默认的byName方式进行装配;
(3)如果(2)不成功,则按byType的方式自动装配。
? ?(4)都不成功,则报异常。
代码:
public class Student {
private String name;
@Resource(name = "teacher2")
private Teacher teacher;
@Autowired
private Book book;
//set,get,有参构造,无参构造
}
XML:
<bean id="teacher2" class="com.yixin.dao.Teacher">
<property name="name" value="王老师"/>
<property name="id" value="1"/>
</bean>
<bean id="book" class="com.yixin.dao.Book">
<property name="name" value="Java编程思想"/>
<property name="id" value="1"/>
</bean>
<bean id="teacher" class="com.yixin.dao.Teacher">
<property name="name" value="王老师"/>
<property name="id" value="1"/>
</bean>
<bean id="student" class="com.yixin.dao.Student" >
<property name="name" value="一心"/>
</bean>
2.2.4 @Autowired与@Resource异同
相同:两者都是实现自动装配功能,都可以写在字段上,或写在setter方法上。 不同: (1)执行顺序不同,@Autowired(未指定name的情况下)先byType,再byName,@Resource先byName,再byType。
(2)@Resource中的name属性一旦指定,就只会按照名称进行装配。
(3)@Autowired默认按类型装配,默认情况下必须要求依赖对象必须存在,如果要允许null 值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用。
(4)@Autowired是Spring定义的; @Resource是java规范。
结语
以上就是一心同学对Spring中自动装配的讲解了,通过这个自动装配可以让我们省了很大力气,在平时开发中更推荐使用注解。
|