idea autowired报红,spring autowired注解

  idea autowired报红,spring autowired注解

  00-1010前言Spring为什么不推荐用@Autowired标注后台原因?关于解决方案的思考@ autowired,@ qualifier,@ resource,它们有什么区别?参考文件

  00-1010请看以下问题。

  Spring为什么不推荐使用@Autowired标注?为什么推荐使用@Resource而不是@Autowired批注?如何快速使用construct injection代替@Autowired?@ autowired、@ qualifier、@ resource,它们有什么区别?下面,我们带着以上问题进行梳理和学习,体会知识之间的关联。

  

目录

  在10月10-1010日做开发的同学可能都会发现,idea给我们经常使用的@Autowired注释加了一个警告。警告内容为:不建议现场注射,翻译为3360不推荐使用属性注入.

  我们点击右边的三个点来查看描述,可以看到以下信息。

  原因描述:3360检查信息3360 Spring团队建议3360 在您的beans中始终使用基于构造函数的依赖注入。对于强制依赖项,始终使用断言。翻译成:Spring 团队建议: 始终在您的 bean 中使用基于构造函数的依赖注入。始终对强制依赖项使用断言

  

前言

为什么Spring建议我们在Bean中使用构造注入?要回答这个问题,我们需要了解Spring的依赖注入(DI)方法。Spring中常用的注入方法有:简单类型注入、集合类型注入、自动域属性注入、自动类别注入、空值注入和构造注入,可以简化为3360属性注入, 构造方法注入, set 方法注入.

  下面, 来用代码展示下三种方式注入

  属性注入可以看到我们在开发最常用的就是属性注入

  @ RestControllerpublic class AppointmentNumberConfigurationController { @ auto wired private AppointmentNumberConfigurationService numberConfigurationService;}set 方法注入集合方法注入也会使用@Autowired标注,但是和属性注入不同,属性注入是用在成员变量上,而set 方法的时候,是用在成员变量的Setter函数上。.

  @ RestControllerpublic class AppointmentNumberConfigurationController { private AppointmentNumberConfigurationService numberConfigurationService;@ Autowired public void setNumberConfigurationService(appointment numberConfigurationService numberConfigurationService){ this . numberConfigurationService=numberConfigurationService;}构造方法注入构造函数注入就是构造函数注入,这是最推荐的使用方式。但是,每次注入都按照这样的流程去构造注入的话, 会显得比较麻烦,至于如何简化这一步,

  我们可以继续往下看.

  

@RestControllerpublic class AppointmentNumberConfigurationController { final AppointmentNumberConfigurationService numberConfigurationService; public AppointmentNumberConfigurationController(AppointmentNumberConfigurationService numberConfigurationService) { this.numberConfigurationService = numberConfigurationService; } }
三种方式对比如下

  

  使用属性注入可能会出现的问题

  

基于属性注入的方式, 违背单一职责原则因为现在的业务一般都会使用很多依赖, 但拥有太多的依赖通常意味着承担更多的责任,而这显然违背了单一职责原则.并且类和依赖容器强耦合,不能在容器外使用。
基于属性注入的方式, 容易导致Spring 初始化失败因为现在在Spring特别是Spring Boot使用中, 经常会因为初始化的时候, 由于属性在被注入前就引用而导致npe(空指针错误),进而导致容器初始化失败(类似下面代码块). Java 在初始化一个类时,是按照 静态变量或静态语句块 –> 实例变量或初始化语句块 –> 构造方法 -> @Autowired 的顺序。所以在执行这个类的构造方法时,person 对象尚未被注入,它的值还是 null。
通过@Autowired 注入, 又因为是 ByType 注入, 因此有可能会出现两个相同的类型bean如下代码快, 就会产生两个相同的Bean, 进而导致Spring 装配失败
//2. 基于属性注入的方式, 容易导致Spring 初始化失败@Autowiredprivate Person person;private String company;public UserServiceImpl(){ this.company = person.getCompany();}//3. 通过@Autowired 注入, 又因为是 ByType 注入, 因此有可能会出现两个相同的类型beanpublic interface IUser { void say();}@Servicepublic class User1 implements IUser{ @Override public void say() { }}@Servicepublic class User2 implements IUser{ @Override public void say() { }}@Servicepublic class UserService { @Autowired private IUser user;} 

  

解决

如果一定要使用属性注入, 可以使用 @Resource 代替 @Autowired 注解@Resource的作用相当于@Autowired,只不过@Autowired按照byType自动注入。如果我们想使用按照名称byName来装配,可以结合@Qualifier注解一起使用。

  如果可能的话, 尽量使用构造注入Lombok提供了一个注解@RequiredArgsConstructor, 可以方便我们快速进行构造注入, 例如:

  

@RestController@RequiredArgsConstructorpublic class AppointmentNumberConfigurationController { final AppointmentNumberConfigurationService numberConfigurationService; }
同时需要注意:

  使用@RequiredArgsConstructor注解需要导入Lombok 包 或者安装lombok 插件

  

 <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.16</version> </dependency>
必须声明的变量为final

  根据构造器注入的,相当于当容器调用带有一组参数的类构造函数时,基于构造函数的 DI 就完成了,其中每个参数代表一个对其他类的依赖。基于构造方法为属性赋值,容器通过调用类的构造方法将其进行依赖注入

  

  

思考

为什么推荐使用@Resource,不推荐使用@Autowired

  通过对问题1 的梳理, 我们可以知道.因为@Autowired 注解在Bean 注入的时候是基于ByType, 因此会由于注入两个相同类型的Bean导致装配失败

  @Resource的作用相当于@Autowired,只不过@Autowired按照byType自动注入。如果我们想使用按照名称byName来装配,可以结合@Qualifier注解一起使用。

  @Resource装配顺序:①如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。②如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常。③如果指定了type,则从上下文中找到类似匹配的唯一bean进行装配,找不到或是找到多个,都会抛出异常。④如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配。

  

因此, 如果一定要使用属性注入, 可以使用 @Resource 代替 @Autowired 注解

  

  

@Autowired, @Qualifier, @Resource, 三者有何区别

@Autowired: 通过byType 方式进行装配, 找不到或是找到多个,都会抛出异常。@Qualifier: 如果想让@Autowired 注入的Bean进行 byName装配, 可以使用 @Qualifier 进行指定@Resource :作用相当于@Autowired,只不过 @Resource 默认按照byName方式装配, 如果没有匹配, 则退回到 byType 方式进行装配

  

参考文档

为什么IDEA不推荐你使用@Autowired?

  @Autowired和@Resource的区别是什么?

  到此这篇关于为什么Spring和IDEA都不推荐使用 @Autowired 注解的文章就介绍到这了,更多相关Spring IDEA @Autowired 注解内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: