Bean的自动装配
Bean的自动装配
- 自动装配是使用spring满足bean依赖的一种方法
- spring会在应用上下文中为某个bean寻找其依赖的bean。
Spring中bean有三种装配机制,分别是:
- 在xml中显式配置;
- 在java中显式配置;
- 隐式的bean发现机制和自动装配。
项目创建
一个人有两个宠物
Cat
package com.q.pojo;
public class Cat {
public void shout(){
System.out.println("Cat,喵喵");
}
}
Dog
package com.q.pojo;
public class Dog {
public void shout(){
System.out.println("Dog,汪汪!!");
}
}
People
package com.q.pojo;
import java.security.PrivateKey;
public class People {
private Cat cat;
private Dog dog;
private String name;
public People() {
}
public People(Cat cat, Dog dog, String name) {
this.cat = cat;
this.dog = dog;
this.name = name;
}
@Override
public String toString() {
return "People{" +
"cat=" + cat +
", dog=" + dog +
", name='" + name + '\'' +
'}';
}
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
people.xml
byName
:根据属性名
自动装配,检查IoC容器并根据名字查找与属性完全一致的bean,并将其与属性自动装配。
因此bean的id只有为dog
或者cat
才能够被找到
byType
:根据属性类型
自动装配
- 如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配
- 如果存在多个该类型bean,那么抛出异常,并指出不能使用byType方式进行自动装配;
- 如果没有找到相匹配的bean,则什么事都不发生
<?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.xsd">
<bean id="cat" class="com.q.pojo.Cat"></bean>
<bean id="dog" class="com.q.pojo.Dog"></bean>
<bean id="people" class="com.q.pojo.People">
<property name="cat" ref="cat"></property>
<property name="name" value="青岚"></property>
<property name="dog" ref="dog"></property>
</bean>
<!--ByName 在上下文中查找,和自己set方法的后面的值一样-->
<bean id="people1" class="com.q.pojo.People" autowire="byName">
<property name="name" value="青岚"></property>
</bean>
<!--ByType 在上下文中查找相同类型注入 类型一致-->
<bean id="people2" class="com.q.pojo.People" autowire="byType">
<property name="name" value="青岚"></property>
</bean>
</beans>
注解实现自动装配
@Autowired和@Resource的相同点:
都是用于自动装配的,都可以放在属性字段和set方法上
@Autowired和@Resource的区别:
@Autowired为Spring提供的注解,@Resource为java提供的注解
@Autowired 默认通过 byType 的方式实现,如果有多个对象,则通过 byName 查找,如果都找不到,则报错;此时可以用@Qualifier指定唯一的bean对象
@Resource 默认通过 byName 的方式实现,如果找不到名字, 则通过 byType 实现!如果两个都找不到,就会报错
要使用注解:
xml中导入约束
<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">
xml中配置注解支持
context:annotation-config/
1
@Autowired
直接在属性上使用即可,此时就可以省略set方法
也可以在set方法上使用(适用于在set方法里面写一些处理逻辑的情况)
beans.xml
context:annotation-config/
<bean id="cat1" class="pojo.Cat"/>
<bean id="dog1" class="pojo.Dog"/>
<bean id="people" class="pojo.People">
<property name="name" value="zsr"/>
</bean>
运行测试类,成功
自动装配环境很复杂的情况下:假设此时有两个cat和dog对象
<bean id="cat1" class="pojo.Cat"/>
<bean id="cat2" class="pojo.Cat"/>
<bean id="dog1" class="pojo.Dog"/>
<bean id="dog2" class="pojo.Dog"/>
<bean id="people" class="pojo.People">
<property name="name" value="zsr"/>
</bean>
发现直接爆红了
这是因为无法匹配到对应的属性,@Autowired 默认通过 byType 的方式实现,如果有多个对象,则通过 byName 查找,如果都找不到,则报错;
此时通过有两个相同类型的对象,通过类型无法找到,bean id也不与属性名相同,通过名字也找不到,所以报错;
这时候就需要配合@Qualifier来使用,指定唯一的bean对象来注入
再次运行,即可成功
@Qualifier还可以设置required属性值为false 允许属性值为null
@Resource
我们将上述的Autowired换成Resource
xml文件为:
<bean id="cat1" class="pojo.Cat"/>
<bean id="cat2" class="pojo.Cat"/>
<bean id="dog1" class="pojo.Dog"/>
<bean id="dog2" class="pojo.Dog"/>
<bean id="people" class="pojo.People">
<property name="name" value="zsr"/>
</bean>
直接运行
发现报错了,这是因为我们无法匹配到对应的属性,@Resource 默认通过 byName 的方式实现,如果找不到名字, 则通过 byType 实现!如果两个都找不到,就会报错
此时,名字cat1/cat2/dog1/dog2不匹配,且每个类型的bean不唯一,所以通过名字和类型都找不到,因此报错
如果我们将其中一个bean的id改为对应的属性名cat和dog
这是因为我们通过名字找到了
我们还有另一种解决方式,不用更改bean的id,我们在@Resource里面添加name属性
通过设置name属性指定装配的对象
此时再运行,成功注入
本文来自博客园,作者:致非,转载请注明原文链接:https://www.cnblogs.com/mycity/p/autowired.html