bean的自动装配
- 自动装配是 Spring 满足 bean 依赖的一种方式
- Spring 会在上下文中自动寻找,并自动给 bean 装配属性
在 Spring 中有三种装配方式
- 在xml中显式配置
- 在java中显式配置
- 隐式自动装配
1. 测试
环境搭建
public class Bired {
public void behavior(){
System.out.println("fly");
}
}
public class Tiger {
public void behavior(){
System.out.println("run");
}
}
public class Zoo {
private Bired bired;
private Tiger tiger;
private String name;
public Bired getBired() {
return bired;
}
public void setBired(Bired bired) {
this.bired = bired;
}
public Tiger getTiger() {
return tiger;
}
public void setTiger(Tiger tiger) {
this.tiger = tiger;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Zoo{" +
"bired=" + bired +
", tiger=" + tiger +
", name='" + name + '\'' +
'}';
}
}
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="bired" class="com.yl.pojo.Bired"/>
<bean id="tiger" class="com.yl.pojo.Tiger"/>
<bean id="zoo" class="com.yl.pojo.Zoo">
<property name="name" value="红山动物园"/>
<property name="bired" ref="bired"/>
<property name="tiger" ref="tiger"/>
</bean>
</beans>
@Test
public void behavior(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Zoo zoo = context.getBean("zoo", Zoo.class);
zoo.getBired().behavior();
zoo.getTiger().behavior();
}
2. byname自动装配
<!--byname 会自动在容器上下文中查找,和自己对象set方法后的值对应的bean id-->
<bean id="zoo" class="com.yl.pojo.Zoo" autowire="byName">
<property name="name" value="红山动物园"/>
</bean>
3. bytype自动装配
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="bired11" class="com.yl.pojo.Bired"/>
<bean id="tiger22" class="com.yl.pojo.Tiger"/>
<!--byname 会自动在容器上下文中查找,和自己对象set方法后的值对应的bean id-->
<!--bytype 会自动在容器上下文中查找,和自己对象属性相同的bean-->
<bean id="zoo" class="com.yl.pojo.Zoo" autowire="byType">
<property name="name" value="红山动物园"/>
</bean>
</beans>
小结:
- byname,需要保证所有bean的id惟一,且该bean需要和自动注入的属性的set方法的值一致
- bytype,需要保证所有bean的class惟一,且该bean需要和自动注入的属性类型一致
4. 使用注解实现自动装配
jdk1.5后支持注解 Spring2.5后支持注解
在配置 Spring 时,注解是否比 XML 更好?
视情况而定
-
导入约束
xmlns:context="http://www.springframework.org/schema/context"
-
配置注解支持
<context:annotation-config/>
<?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/> </beans>
@Autowired
直接在属性上使用,也可在 set 方法上使用
无需写 set 方法,前提是自动装配的属性在 IOC 容器中存在,且符合名字 byname
@Nullable
字段标记了该注解,该字段可以为null
public Zoo(@Nullable String name) {
this.name = name;
}
public @interface Autowired {
boolean required() default true;
}
@Test
public void behavior(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Zoo zoo = context.getBean("zoo", Zoo.class);
zoo.getBired().behavior();
zoo.getTiger().behavior();
}
若@Autowired自动装配环境复杂,自动装配无法通过一个注解@Autowired完成时,可用@Qualifier(value = “对象名”)配合@Autowired使用,指定惟一的bean对象注入
@Autowired()
@Qualifier(value = "bired1")
private Bired bired;
@Autowired
@Qualifier(value = "tiger2")
private Tiger tiger;
private String name;
@Resource 先判断属性,再判断类型,若都不存在则报错
需导包
import javax.annotation.Resource;
可指定对象
@Resource(name = "bired1")
private Bired bired;
@Resource与@Autowired的区别
- 都用于自动装配,可以放在属性字段上
- @Autowired 通过 bytype 实现,必须要求该对象存在
- @Resource 默认通过 byname 实现,不存在则通过 bytype 实现,都不存在就报错
- 执行顺序不同
- @Autowired 通过 bytype 实现
- @Resource 默认通过 byname 实现