⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 juejin.cn/post/7265926762729717819 「podongfeng」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注微信公众号:【芋道源码】有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言都将得到认真回复。甚至不知道如何读源码也可以请教噢。
  4. 新的源码解析文章实时收到通知。每周更新一篇左右。
  5. 认真的源码交流微信群。

一个警告

近期团队里来了新同学,依赖注入的时候习惯使用@Autowired,发现被idea黄色警告,跑过来问我。借着这个机会,我给大家同步一些心得。

首先看下问题的现象,使用@Autowired被idea警告,而使用@Resource则不会:

@Autowired被idea警告

@Resource

@Autowired和@Resource的差异

来源

  • @Resource是JSR 250中的内容,发布时间是2006年
  • @Autowired是Spring2.5中的内容,发布时间是2007年

@Resource是JSR的标准,Spring框架也提供了实现。既然@Autowired是在@Resource之后发布的,应该就有@Resource不能表达的含义或者不能实现的功能。

用法

注入方式

虽然我们开发中使用最多的方式是属性注入,但其实存在构造函数注意、set方法注入等方式。相比于@Resource支持的属性注入和set方法注入,@Autowired还能支持构造方法注入的形式,@Resource是不行的。

可指定属性

@Autowired支持required属性

@Resource支持7个其它属性

bean查找策略

  • @Autowired是类型优先,如果这个类型的bean有多个,再根据名称定位
  • @Resource是名称优先,如果不存在这个名称的bean,再去根据类型查找

查找过程

@Autowired

@Resource

思考

对于大多数开发同学来说,@Autowired 和 @Resource 差异是很小的,虽然 @Autowired 多支持构造器注入的形式,但是直接属性注入真的太灵活太香了。而@Autowired晚生于@Resource,既然已经有JSR标准的@Resource,还要增加1个特有Autowired,必然有Spring的考虑。

个人认为,构造器注入和支持属性不同这个理由是很弱的,这些特性完全可以在@Resource上实现,也不违反JSR的约束。比较可能的原因是,含义的不同,而最大的不同体现在bean查找策略上,@Autowired默认byType,@Resource默认byName,这个不同其实隐含了,@Resource注入的bean,更加有确定性,你都已经确定了这个bean的名称了,而类型在Java中编译过程本身是个强依赖,其实这里相当于指定了类型和名称,注入的是一个非常确定的资源。而@Autowired是类型优先,根据类型去查找,相比于@Resource,确定性更弱,我知道这里要注入bean的类型,但是我不确定这个bean的名称,也隐含体现了java多态的思想。

总结

回到开篇的idea的警告,网上有很多人都赞同的一种说法是,@Resource是JSR规范,@Autowired是Spring提供,不推荐使用绑定了Spring的@Autowired,因为@Resource在更换了框架后,依然可以使用。我不太赞同这种说法,因为idea的错误提示很明确,「Field injection is not recommended」,不推荐使用属性注入的方式,那换成@Resource,我理解并没有解决这个问题,虽然idea确实不警告了,可能有点掩耳盗铃的意思。
比较推荐的做法是,使用构造方法注入,虽然很多时候会有点麻烦,特别是增加依赖的时候,但是正是这种麻烦,会让你不再那么随意做属性注入,更能保持类的职责单一。然后配合lombok,也可以让你省去这种麻烦,不过希望还是能通过这个警告时刻提醒自己保持类的职责单一。

文章目录
  1. 1. 一个警告
  2. 2. @Autowired和@Resource的差异
    1. 2.1. 来源
  3. 3. 用法
    1. 3.1. 注入方式
    2. 3.2. 可指定属性
    3. 3.3. bean查找策略
  4. 4. 查找过程
    1. 4.1. @Autowired
    2. 4.2. @Resource
    3. 4.3. 思考
  5. 5. 总结