使用IDEA开发的时候有没有注意到提示?在字段上使用Spring的依赖注入注解@Autowired后,会出现如下警告:Fieldinjectionisnotrecommended(不推荐字段注入)但是使用@Resource时不会出现这个提示。网上的文章大多介绍了两者的区别,而没有提及原因。当时我想了很久,想出了一个可能的原因。今天我总结一下。另外整理了最新的Spring面试题,大家可以在Java面试库小程序在线写题。Spring常用的DI方法构造器注入:使用构造方法注入参数依赖Setter注入:调用Setter方法注入依赖字段注入:在字段上使用@Autowired/Resource注解推荐一个开源免费的SpringBoot最全教程:https://github.com/javastacks/spring-boot-best-practice@AutowiredVS@Resource其实它们的基本功能都是通过注解实现依赖注入,只不过@Autowired是Spring定义的,而@Resource是JSR-250定义的。依赖标识方式:@Autowired默认为byType,可以使用@Qualifier指定Name。@Resource默认为ByName。如果找不到,则ByType适用于对象:@Autowired可用于构造函数、方法、参数和字段。@Resource只能用于方法,字段使用。Provider:@Autowired由Spring提供,@Resource由JSR-250提供。各种DI方式的优缺点参考Spring官方文档,建议如下使用场景:构造函数注入:强依赖(即必须使用这个依赖),不可变性(每个依赖不会频繁变化)。Setter注入:可选(在没有这种依赖的情况下工作),可变的(依赖经常变化)。Fieldinjection:在大多数情况下,尽可能少地使用fieldinjection。如果必须使用它,@Resource与IoC容器的耦合程度低于@Autowired。Field注入的缺点是不能像构造函数那样注入不可变对象。依赖关系对外界是不可见的。外界可以看到constructor和setter,但是看不到私有字段,自然无法理解需要的依赖。会导致组件与IoC容器紧密耦合(这是最重要的原因,离开IoC容器使用组件会导致依赖注入变得非常困难)。因此,单元测试也必须使用IoC容器。原因是当依赖太多的时候不明显。例如,如果我需要10个依赖项,那么使用构造函数注入将是巨大的。这时候就应该考虑这个组件是否违反了单一职责原则。为什么IDEA只警告@AutowiredField注入有很多缺点,但是它的好处也不容忽视:太方便了。使用constructor或者setter注入需要写更多业务无关的代码,非常麻烦,而字段注入大大简化了它们。而且在大多数情况下,业务代码和框架是强绑定的,完全的松散耦合只是理想中的事情,牺牲敏捷性去过度追求松散耦合是得不偿失的。那么问题来了,为什么IDEA只警告@Autowired,而忽略了@Resource呢?另外整理了最新的Spring面试题,大家可以使用Java面试库小程序在线刷题。在我看来,正如我们前面提到的:@Autowired是由Spring提供的,它是由特定的IoC提供的特定注解,从而导致应用程序和框架之间的强绑定。一旦切换到其他IoC框架,是不支持注入的。而@Resource是由JSR-250提供的,它是一个Java标准。我们使用的IoC容器要与之兼容,这样即使更换了容器也能正常工作。
