大数跨境
0
0

这才是 @Resource 和 @Autowired 的真正区别

这才是 @Resource 和 @Autowired 的真正区别 终码一生
2022-09-28
0

点击“终码一生”,关注,置顶公众号

每日技术干货,第一时间送达!



1

@Resource


@Resource是Java自己的注解


先来看一下源码:



@Resource有两个属性是比较重要的,分别是name和type;Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。默认按name进行注入。


下面看一下这样的一个变量注入方式:



按type进行注入的自动注入策略,这个type指的就是类的类型,可以这样理解,比如Apple.class,类型就是Apple,Person.class,类型就是Person。



如果我有两个Person类,这个时候就无法辨别注入对象,就可以使用name属性去辨别。


在spring中, 被@Component标识的类会在servlet容器启动时加载单实例(默认设置下),用@Resource注解可以注入,如果需要的bean没有被提前加载, 则会报错。


在加载的时,是根据类名(不包括package地址)判断,出现重复的类名会报异常(不在同一个package, 也会报异常)。如果类名相同,可以标识成不同的bean,然后@Resource的name去辨别。


假设,有两个相同的实现类,那么可以用name去辨别,如下:


@Service("a")
public class ReportServiceImpl implements ReportService{
    ......
}

@Service("b")
public class ReportServiceImpl implements ReportService{
    ......
}


注入的时候指定名称为a的那个实现类:



这样指定,就知道是哪一个了。



2

@AutoWired


@AutoWired是spring的注解,Autowired只根据type进行注入,不会去匹配name。如果涉及到type无法辨别注入对象时,那需要依赖@Qualifier或@Primary注解一起来修饰。@Resource默认按名称方式进行bean匹配,@Autowired默认按类型方式进行bean匹配。


使用@AutoWired变量注解方式时,会有黄色波浪线,idea会提示:



Spring团队建议:“在bean中始终使用基于构造函数的依赖注入。始终对强制依赖项使用断言”。


意思是说,用@AutoWired的注入时,尽量用基于构造函数的依赖注入,而不是变量的方式注入。


这就是构造函数方式的依赖注入:



再来看一下@AutoWired注解的源码:



只有required属性,没有其他属性了,根据type进行注入。


用@AutoWired的变量注入时,如果碰到无法分辨的对象,就无法注入成功。但是可以结合@Qualifier注解使用,表明哪个实现类才是我们需要的。



但是仍然不建议使用变量注入方式


1、可能会造成NPE,如下:


public class TestController {
  @Autowired
  private TestService testService;
  private String name;
  public TestController(){
    this.name= testService.getName();
  }
 }


这段代码执行时会报NPE。Java类会先执行构造函数,然后在通过@Autowired注入实例,二构造函数里面需要注入的对象,因此在执行构造函数的时候就会报错。


2、还可能回导致循环依赖,即A里面注入B,B里面又注入A。


注:在代码中发现构造方法中注入了很多依赖,显得很臃肿,对于这个问题,说明类中有太多的责任,违反了类的单一性职责原则,这时候需要考虑使用单一职责原则进行代码重构。


 

3

总结


简单来说,这两的区别就是:


  • @Resource:java的注解,属性较多,type无法分辨时可以用name分辨

  • @Autowired:spring的注解,一个属性,type无法分辨时需要借助@Qualifier注解才能使用,使用@Autowired方式最好使用构造函数的方式注入。


很简单的一个例子,有两个苹果,一个叫哈哈,一个叫呵呵,你指着两个苹果,意思是去拿个苹果,让@Resource去拿,如果不说明,他懵了,但是你说明拿叫哈哈的那个,他就知道了,给你拿来了,让@Autowired去拿,如果不说明,他也懵了,但是他又是个聋子,听不到你说的,结果就拿不到,但是如果写了个字条(@Qualifier)写明拿呵呵,他也就知道了。


来源:blog.csdn.net/mrxutada/article/details/118811930


PS:防止找不到本篇文章,可以收藏点赞,方便翻阅查找哦。 


往期推荐



SpringBoot 项目优雅实现 Excel 导入导出功能

老司机教你,如何画出优秀的技术架构图?

说实话,DataGrip真得牛逼,只是你不会用而已~

SQL优化 20 连击,建议收藏!

记一次堆外内存泄露,整个团队通宵处理到爆肝!

图解 SQL 执行顺序,通俗易懂!

Notepad++ 替代品开源了,好用 !!!


【声明】内容源于网络
0
0
终码一生
开发者聚集地。分享Java相关开发技术(JVM,多线程,高并发,性能调优等),开源项目,常见开发问题和前沿科技资讯!
内容 1876
粉丝 0
终码一生 开发者聚集地。分享Java相关开发技术(JVM,多线程,高并发,性能调优等),开源项目,常见开发问题和前沿科技资讯!
总阅读481
粉丝0
内容1.9k