@Autowired和@Resource注解的区别和联系

作者:陆金龙    发表时间:2022-01-12 20:35   

关键词:@Resource  @Autowired  

推荐使用@Resource对字段进行注解。这样就不用写setter方法了.并且这个注解是属于J2EE的,减少了与Spring的耦合

共同点:

都可以通过byType和byName两种方式注入。

没有显示指定时,优先尝试通过一种方式注入,如不成功则切换到另一种方式。

注1:其中byName匹配规则。@Autowired或@Resource指定了name属性,取name属性值。如果没有指定name属性,取注解的字段名(变量名)。

注2:待匹配的bean,如果没有指定自己的name,则默认为类型名的首字母小写形式。例如:@Service public class TestServiceImpl implements TestService,@Service没指定bean的value属性,则注入bean的名字就是类名首字母小写,即"testServiceImpl"。

差异对比:

@Autowired

@Autowired注解是Spring提供的。

@Autowird注解默认优先通过byType方式注入。

@Autowired可通过变量名匹配name。或者配合@Qualifier注解来显式指定name值,如:@Autowired @Qualifier(value = "aServiceImpl")。

@Autowired注解注入的对象需要在IOC容器中存在,否则需要加上属性required=false,表示忽略当前要注入的bean。

 

@Autowired首先通过byType注入,判断类型。如果有多个实现,无法确定具体是哪一个,则通过byName方式。byName方式如果变量名也无法匹配IOC容器中id,则报错。

@Resource

@Resource注解是J2EE本身提供的。

@Resource可以显示指定byName匹配、byType匹配。或者同时指byType和byName匹配,@Resource(name="aServiceImpl",type=AServiceImpl.class)。

(1)默认情况优先通过byName注入:既不指定@Resource的name属性,也不指定type属性。先通过byName方式查找,找不到与名称匹配的bean时,退回按byType进行查找,如果找到一个就注入。

(2)只指定@Resource注解的name属性,则按name后的名字去bean元素里查找有与之相等的name属性的bean。

(3)只指定@Resource注解的type属性,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常。

(4)既指定了@Resource的name属性又指定了type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。

         按类型匹配,查找到实现类有多个,仍然无法确定的,则报错。

 
 
参考:https://blog.csdn.net/qq_45590494/article/details/114444371(@Autowired和@Resource注解的区别和联系(十分详细,不看后悔))
           https://zhuanlan.zhihu.com/p/265982399(@Resource和@Autowired的区别,小白看完这篇你就懂了)
 

注入过程举例:

来源:segmentfault 巅峰大词典

接口

public interface TestService {
    public String test();
}

实现类impl。(没有指定name,则该bean的name为“testServiceImpl”)

@Service
public class TestServiceImpl implements TestService {
    @Override
    public String test() {
        return "TestServiceImpl";
    }
}
Controller的调用:
@RestController
public class TestCtl {
    @Autowired
    private TestService testService;

    @RequestMapping("/test")
    public String test() {
        return testService.test();
    }
}
并没有注入接口的bean,只注入了实现类serviceImpl的bean,接口只是用来接收的。

再来说Controller获取实例的过程:

使用@Autowired,程序在spring的容器中查找类型是TestService的bean,刚好找到有且只有一个此类型的bean,即testServiceImpl,所以就把testServiceImpl自动装配到了controller的实例testService中,testService其实就是TestServiceImpl实现类;

如果使用@Resource,则是先在容器中查找名字为testService的bean,但并没有找到,因为容器中的bean名字是testServiceImpl。然后再通过类型查找TestService类型的bean,找到唯一的了个TestService类型bean(即TestServiceImpl),所以就自动装配实例成功了。