5. Bean 自动装配
2022年9月6日
5. Bean 自动装配
引用类型的自动注入: spring 框架根据某些规则可以给引用类型赋值.
不用你在给引用类型赋值了,使用的规则常用的是 byName, byType.
Spring 的三种装配方式
- xml 文件中显式装配
- 在 java 中显式装配
- 隐式自动装配(autowire)
ByName 自动装配
通过set 方法后面的属性名寻找对应的 bean id, 需要保证所有bean 的 id 唯一,并且这个bean id 需要和自动注入属性的 set 方法的属性名一致
public class Student {
private String name;
private int age;
private School school;
// set方法后面为School(首字母大写) 则配置文件的bean id是school(首字母必须小写)
public void setSchool(School school) {
this.school = school;
}
}
<bean id="student" class="com.demo.di01.Student" autowire="byName"/>
<!--配置文件的id值-->
<bean id="school" class="com.demo.di01.School">
<property name="name" value="school"/>
</bean>
ByType 自动装配
通过该属性的数据类型自动装配(有多个同源的数据类型的属性时无法使用), 需要保证该属性的 bean class 和set 方法的参数类型同源
同源就是一类的意思:
- java 类中set 方法的参数的数据类型和 bean 的 class 的值是一样的
- java 类中set 方法的参数的数据类型和 bean 的 class 的值是父类(参数)和子类(bean)的关系
- java 类中set 方法的参数的数据类型和 bean 的 class 的值是接口和实现类关系的
- 子类
// 子类
@Data
public class PrimarySchool extends School{
public PrimarySchool() {
System.out.println("PrimarySchool");
}
}
- 父类
// 父类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class School {
private String name;
}
- 学生类
public class Student {
private String name;
private int age;
private School school;
public void setSchool(School school) {
System.out.println(school + "aaa");
}
}
- beans.xml
<bean id="student" class="com.demo.di01.Student" autowire="byType"/>
<!--
父类与子类同源, 不能同时存在
<bean id="school" class="com.demo.di01.School">
<property name="name" value="School"/>
</bean>
-->
<bean id="school" class="com.demo.di01.PrimarySchool">
<property name="name" value="PrimarySchool"/>
</bean>
使用注解自动装配
导入约束
xmlns:context="http://www.springframework.org/schema/context"
配置注解的支持
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <context:annotation-config/> <bean id="cat" class="pojo.Cat"/> <bean id="dog" class="pojo.Dog"/> <bean id="person" class="pojo.Person"/> </beans>
@Autowired
@Autowired
, @Qualifier
, @NUllable
- 在 IOC 容器中注册 bean 对象后,可在对应属性上直接使用该注解, 可以不写 set()方法, 该注解默认是通过 ByType 实现
- 该注解也可以在 set()方法上使用
- 该注解可以带参数
@Autowired(required = false)
使用该参数后,该属性值允许为 null 效果和@NUllable
类似
public class Animal {
@Autowired(required = false)
public String name;
public void shut(@Nullable Animal animal) {
System.out.println(animal.name + "shut");
}
}
- 当自动装配的环境比较复杂(有多个相同类型的 bean 对象时),自动装配无法确定具体的 bean 对象,可以使用
@Qualifier(value = "cat")
指定唯一的 bean 对象配合@Autowired
完成自动装配, 此时@Autowired
通过 ByName 实现
@Autowired
@Qualifier(value = "cat")
private animal cat;
java 原生注解@Resource
该注解和@Autowired
相反默认通过 ByName,如果指定了 name,则用 byName 自动装配,如果指定了 type,则用 byType 自动装配
@Resource(name = "dog")
private Animal dog;
总结
@Autowired
和@Resouce
的区别
@Autowired
默认按 byType 自动装配,而@Resource
默认 byName 自动装配@Autowired
只包含一个参数: required,表示是否开启自动注入,默认是 true 而@Resource
包含七个参数,其中最重要的两个参数是: name 和 type@Autowired
如果要使用 byName,需要使用@Qualifier
一起配合而@Resource
如果指定了 name,则用 byName 自动装配,如果指定了 type,则用 byType 自动装配@Autowired
能够用在: 构造器、方法、参数、成员变量和注解上,而@Resource
能用在: 类、成员变量和方法上@Autowired
是 spring 定义的注解,而@Resource
是 JSR-250 定义的注解