项目中我们一般都会用到这三个注解的一个或几个,那么这三个注解有什么区别呢?
笼统来说,我们可以这样认为@Autowired+@Qualifier == @Resource 。
为什么我会这样认为呢?话不多说,代码演示。。。
package com.example.demo.service;
/**
* Created by linjiaming
*/
public interface AnimalService {
String oneSay();
}
package com.example.demo.service.impl;
import com.example.demo.service.AnimalService;
import org.springframework.stereotype.Service;
/**
* Created by linjiaming
*/
@Service
public class CatServiceImpl implements AnimalService {
@Override
public String oneSay() {
return "喵喵喵";
}
}
package com.example.demo.controller;
import com.example.demo.service.AnimalService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by linjiaming
*/
@RestController
public class HelloWorld {
@Autowired
AnimalService animalService;
@RequestMapping("/hello")
public String sayHello(){
return animalService.oneSay();
}
}
package com.example.demo.service.impl;
import com.example.demo.service.AnimalService;
import org.springframework.stereotype.Service;
/**
* Created by linjiaming
*/
@Service
public class DogServiceImpl implements AnimalService {
@Override
public String oneSay() {
return "汪汪汪";
}
}
使用@AutoWired时,项目启动报错
No qualifying bean of type 'com.example.demo.service.AnimalService' available: expected single matching bean but found 2: catServiceImpl,dogServiceImpl
大概意思是说,期望找到对应类型为AnimalService的bean一个,但是找到了两个。
这时候我们使用@Resource注解
这时候启动项目能正常启动访问:
注:若在这种情况使用@Resource的话,需要在括号类指定name属性,否则需搭配@Qualified注解使用
对于@Autowired注解来说,在这种情况下,必须和@Qualifier注解搭配使用
通过代码演示,可以直观的看出三个注解的区别,再进一步对着三个注解进行总结:
@Autowired: 根据类型注入
以这个demo为例,一开始根据类型找到AnimalService,然后找到它的子类型。这时候由于它的子类型有两 个,它就不知道要取哪个,所以这时候就报错。
@Resource :默认根据名字注入,其次按照类型搜索
既不指定name属性,也不指定type属性,则自动按byName方式进行查找。如果没有找到符合的bean,则回 退为一个原始类型进行进行查找,如果找到就注入。
只是指定了@Resource注解的name,则按name后的名字去bean元素里查找有与之相等的name属性bean。
只指定@Resource注解的type属性,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多 个,都会抛出异常。
@Autowired :@Qualifie("dogServiceImpl") 两个结合起来可以根据名字和类型注入