什么!@Resource和@Autowired竟然有这些区别?

作为一只刚工作不到一个月的程序猿,在今天学习公司项目代码时遇到了一个问题:spring容器中一个接口的实现有两个,到底注入哪个呢?具体代码如下:

/**
这是接口
**/
public interface Query {
  String query(string id);
}

/**
这是两个实现类
**/
public class QueryWithCache implement Query {
  public String query(String id) {
    *********
  }
}

public class QueryWithNoCache implement Query {
  public String query(String id) {
    *********
  }
}

/**
在spring中用@Resource注解自动注入,注入代码如下
**/

 @Resource 
 private Query query

根据我入职前多日的刷面试题的经验来看(面试题终于派上用场了),spring中当一个接口有两个实现类时,并且spring无法判断具体是哪个类时会报错。我转念一想,这项目都已经平稳运行N(N>5)年了,肯定不会出现spring容器自动注入都报错,容器都启动不了的情况吧。那spring是怎么完成注入的呢?

随后我打开了spring的配置文件:

<bean id="query" class="QueryWithCache">
    <property name="queryWithNoCache",ref="queryWithNoCache">
</bean>

<bean id="queryWithNoCache" class="QueryWithNoCache">

</bean>

在我以前的印象里 Autowired与Resource这两个注解是等价的,都是按照类型来完成注入的。但是结合项目,很明显Resource这个注解是通过名称来注入的。

那么这两个注解到底有什么区别呢?

刨根问底的我打开了百度,得到了我想要的答案:

首先,出身不同:

Resource竟然不是spring框架里的,而Autowired则是spring里面的:

  import javax.annotation.Resource;
  import org.springframework.beans.factory.annotation.Autowired;

其次呢,Autowired只按照类型注入,不匹配name进行注入。而Resource就比较灵活,默认的话按照name匹配(即示例中的bean的id),Resource可以通过配置它的两个属性:name和type来指定按照类型还是名称注入。

好了,疑云到这里就消散了。示例中使用Resource注解进行注入,Resource默认按名称注入,名称为query的bean是QueryWithCache类型,所以

 @Resource 
 private Query query;

这句注入的是QueryWithCache这个类的bean。

发布于 2019-08-14