简述@Autowired和@Resource的区别

前言

我们知道,在Spring中使用注解进行依赖注入常使用@Autowired和@Resource来实现,下面我们简单提及一下他们之间的区别

@Autowired

我们往往使用@Qualifier来配合其使用,制定到固定的对象上
@Autowired的使用有以下几种情况:

  1. 加在set方法上注入
  2. 加在构造器方法上注入
  3. 直接加在属性之上注入
    我们使用一个公共的类来作为注入的属性:
1
2
3
4
5
6
@Component("people")  //在这里是配置在xml里使用注解后,对bean进行装配的注解
public class People {
public People() {
System.out.println("People");
}
}

加在set方法上:(我们写一个餐馆类来演示)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Component("rest")
public class Restaurant {
private People people;
public Restaurant() {
System.out.println("Restaurant()");
}

// 使用@Autowired,set方法注入(默认byType),@Qualifier("wt")(byName)指定对象
@Autowired
public void setPeople(@Qualifier("people") People people) {
System.out.println("setPeople()");
this.people = people;
}

@Override
public String toString() {
return "Restaurant [people=" + people + "]";
}
}

==Autowired会默认采用”byType”的方法来通过@Autowired制定的setter方法进行装配,结合@Qualifier可以指定装配的具体对象(容器中已经声明过的)==

加载传参的构造器上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Component("school")
public class School {
private People people;

public School() {
System.out.println("School()");
}
//构造器方式注入
@Autowired
public School(@Qualifier("people") People people) {
System.out.println("School(people)");
this.people = people;
}
@Override
public String toString() {
return "School [people=" + people + "]";
}

}

构造器上加@Autowired只是改变了注入的方式,其他与set方法相同

直接加在属性上:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Component("rest")
public class Restaurant {
//此时有没有set方法都可以,会使用反射加进去。
@Autowired
@Qualifier("people")
private People people;
public Restaurant() {
System.out.println("Restaurant()");
}

@Override
public String toString() {
return "School [people=" + people + "]";
}
}

当@Autowired加在属性上时,就不通过构造器或set方法进行注入了,而是进行反射注入,@Qualifier依旧可以指定注入的对象。

@Resource

相比@Autowired,==@Resource不会使用构造器方式进行注入==
有以下两种情况:

  1. @Resource在set方法上进行注入
  2. @Resource在属性上进行注入

在set方法上进行注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Component
public class Bar {

private People people;
public Bar() {
System.out.println("Bar()");
}

@Resource(name="people")
public void setPeople(People people) {
this.people = people;
}
@Override
public String toString() {
return "Bar [people=" + people + "]";
}
}

值得注意的是,==默认情况下,@Resource会根据”byName”进行setter装配注入,若找不到对应name,才会进行”byType”方式的注入,可以通过指定name来确定对象==

在属性上进行注入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Component
public class Bar {
@Resource
private People people;
public Bar() {
System.out.println("Bar()");
}

public void setPeople(People people) {
this.people = people;
}
@Override
public String toString() {
return "Bar [people=" + people + "]";
}
}

==当@Resource在属性前时,会默认使用属性名来进行”byName”注入。==

总结

  1. 在装配方式上:
  • @Auotwired:默认使用”byType”方式进行装配,使用@Qualifier指定对象消除混乱
  • @Resource:默认使用”byName”,当找不到对应Name时才进行”byType”装配,可以使用name对容器中的对象名进行指定(此时将无法进行”byType”装配)
  1. 使用位置:
  • @Auotwired:可以在属性上、set方法上、带参构造器上
  • @Resource:属性上、set方法上

==注*: @Auotwired所有加@Qualifier和 @Resource带name指定的地方都可以删去,只是将无法指定容器装配过的对象,会自动在容器中查找==