详解Spring中Bean的自动装配~

目录

  1. 环境搭建
  2. byName、byType
  3. 使用注解实现自动装配
    @Autowired
    @Resource
    小结
    自动装配是Spring满足bean依赖的一种方式
    Spring会在上下文中自动寻找,并且自动给bean装配属性
  4. 环境搭建
    一个人有猫和狗两个宠物

结构图:
image-20200805152406109
Cat.java

package pojo;

public class Cat {
public void shout() {
System.out.println(“喵~”);
}
}
1
2
3
4
5
6
7
Dog.java

package pojo;

public class Dog {
public void shout() {
System.out.println(“汪~”);
}
}
1
2
3
4
5
6
7
People.java

package pojo;

public class People {
private Cat cat;
private Dog dog;
private String name;

public void setCat(Cat cat) {
    this.cat = cat;
}

public void setDog(Dog dog) {
    this.dog = dog;
}

public void setName(String name) {
    this.name = name;
}

public Cat getCat() {
    return cat;
}

public Dog getDog() {
    return dog;
}

public String getName() {
    return name;
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
beans.xml

<?xml version="1.0" encoding="UTF-8"?>

<bean id="cat" class="pojo.Cat"/>
<bean id="dog" class="pojo.Dog"/>
<bean id="people" class="pojo.People">
    <property name="name" value="zsr"/>
    <property name="dog" ref="dog"/>
    <property name="cat" ref="cat"/>
</bean>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 MyTest.java

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import pojo.People;

public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(“beans.xml”);
People people = context.getBean(“people”, People.class);
people.getDog().shout();
people.getCat().shout();
System.out.println(people.getName());
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
测试:

image-20200805152749240
到此环境搭建成功!

  1. byName、byType

上述代码中,ref就是寻找对应的cat和dog对象;如果有一种机制,能够自动在bean里面寻找我们要设置的cat或者dog,自动装配,就不用写下面的那两行代码了!这就引入了自动装配

我们更改一下.xml文件,删除那两行代码,加入autowire属性,发现有几种可以选择,这里先选择byName
image-20200805153956150

1 2 3 4 5 再次运行测试类,依旧成功,说明我们的cat和dog被自动设置到了people中 image-20200805153732343 那我们再更改一下,将dog改为dog1 1 2 3 4 5 再进行测试,发现空指针异常 image-20200805153919732 为什么??

byName:根据属性名自动装配,检查IoC容器并根据名字查找与属性完全一致的bean,并将其与属性自动装配。

因此bean的id只有为dog或者cat才能够被找到

我们再改一下,将byName改为byType

1 2 3 4 5 再次运行,又成功了 image-20200805161016746 byType:根据属性类型自动装配

如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配
如果存在多个该类型bean,那么抛出异常,并指出不能使用byType方式进行自动装配;
如果没有找到相匹配的bean,则什么事都不发生
必须保证类型全局唯一,如果多加一个dog,则报错:
image-20200805161547606
可以省略id

1 2 3 4 5 小结

byName的时候,需要保证所有bean的id唯一,并且这个bean id需要和实体类中对应的属性名相同
byName的时候,需要保证所有bean的class唯一,并且这个bean id需要和自动注入属性的类型一致;可以省略id

  1. 使用注解实现自动装配
    jdk1.5支持注解,Spring2.5支持注解

要使用注解:

xml中导入约束


1
2
3
4
5
6
7
xml中配置注解支持

context:annotation-config/
1
@Autowired
直接在属性上使用即可,此时就可以省略set方法
也可以在set方法上使用(适用于在set方法里面写一些处理逻辑的情况)
image-20200805194313281
beans.xml
context:annotation-config/

1 2 3 4 5 6 7 运行测试类,成功 image-20200805194601311 自动装配环境很复杂的情况下:假设此时有两个cat和dog对象

context:annotation-config/

1 2 3 4 5 6 7 8 9 发现直接爆红了 image-20200805194806760 这是因为无法匹配到对应的属性,@Autowired 默认通过 byType 的方式实现,如果有多个对象,则通过 byName 查找,如果都找不到,则报错;

此时通过有两个相同类型的对象,通过类型无法找到,bean id也不与属性名相同,通过名字也找不到,所以报错;

这时候就需要配合@Qualifier来使用,指定唯一的bean对象来注入
image-20200805195309327
再次运行,即可成功

@Qualifier还可以设置required属性值为false 允许属性值为null
image-20200805220439391

@Resource
我们将上述的Autowired换成Resource
image-20200805213027370
xml文件为:

context:annotation-config/

1 2 3 4 5 6 7 8 9 直接运行 image-20200805213349045 发现报错了,这是因为我们无法匹配到对应的属性,@Resource 默认通过 byName 的方式实现,如果找不到名字, 则通过 byType 实现!如果两个都找不到,就会报错

此时,名字cat1/cat2/dog1/dog2不匹配,且每个类型的bean不唯一,所以通过名字和类型都找不到,因此报错

如果我们将其中一个bean的id改为对应的属性名cat和dog

1 2 3 4 5 6 7 再次运行,成功了 image-20200805213800158 这是因为我们通过名字找到了 我们还有另一种解决方式,不用更改bean的id,我们在@Resource里面添加name属性 image-20200805214155735 通过设置name属性指定装配的对象

此时再运行,成功注入
image-20200805215434616

小结
@Autowired和@Resource的相同点:

都是用于自动装配的,都可以放在属性字段和set方法上
@Autowired和@Resource的区别:

@Autowired为Spring提供的注解,@Resource为java提供的注解
@Autowired 默认通过 byType 的方式实现,如果有多个对象,则通过 byName 查找,如果都找不到,则报错;此时可以用@Qualifier指定唯一的bean对象
@Resource 默认通过 byName 的方式实现,如果找不到名字, 则通过 byType 实现!如果两个都找不到,就会报错

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值