使用@Autowired注解出现警告(Field|使用@Autowired注解出现警告:Field injection is not recommended)
使用@Autowired注解出现警告:Field injection is not recommended
- 三种注入方式
- field(变量)注入
- 构造器注入
- set方法注入
- 总结
在idea上打了@Autowired遇到了一个警告,说是spring团队建议使用构造器的方式注入,使用变量依赖注入是不推荐的。想要清楚为什么,就得了解三种注入方式的优缺点
文章图片
三种注入方式 field(变量)注入
@Autowired
private UserService userService;
**优点:**最常见的注入方式,变量方式注入非常简洁,没有任何多余代码,非常有效的提高了java的简洁性。即使再多几个依赖一样能解决掉这个问题。
**缺点:**1. 对于IOC容器以外的环境,除了使用反射来提供它需要的依赖之外,无法复用该实现类。而且将一直是个潜在的隐患,因为你不调用将一直无法发现NullPointException的存在
2. 可能会导致循环依赖,如下面的情况
public class A{
@Autowired
private B b;
}
public class B{
@Autowired
private A a;
}
如果使用构造器注入,在spring项目启动的时候,就会抛出:BeanCurrentlyInCreationException:Requested bean is currently in creation: Is there an unresolvable circular reference?从而提醒你避免循环依赖,如果是field注入的话,启动的时候不会报错,在使用那个bean的时候才会报。
构造器注入
private UserService userService;
@Autowired
public LoginController(UserService userService){
this.userService=userService;
}
**优点:**spring4.X推荐的方式,构造器注入的方式能够保证注入的组件不可变,并且确保需要的依赖不为空。此外,构造器注入的依赖总是能够在返回客户端(组件)代码的时候保证完全初始化的状态。
依赖不可变:即注入对象为final。
依赖不为空:省去了对注入参数的检查,当要实例化FooController的时候,由于自己实现了有参数的构造函数,所以不会调用默认构造函数,那么就需要Spring容器传入所需要的参数,所以就两种情况:1、有该类型的参数->传入,OK 。2:无该类型的参数->报错。所以保证不会为空。
完全初始化状态:跟依赖不为空结合起来,向构造器传参之前,要确保注入内容不为空,那么肯定要调用依赖组件的方法来完成实例化,在java类加载实例化的过程中,如果有父类的话先初始化父类,然后到自己的成员变量,最后才是构造方法。所以返回的都是完全初始化的状态。
**缺点:**当参数过多的时候会显得臃肿。
set方法注入
@Controller
public class UserController {
private UserService userService;
@Autowired
public void setUserService(UserService userService) {
this.userService = userService;
}
}
setter的方式能用让类在之后重新配置或者重新注入。
总结 使用构造器方式注入的好处
1、保证依赖不可变(final关键字)
2、保证依赖不为空(省去对参数的检查)
3、保证返回客户端的代码是完全初始化的状态
4、避免循环依赖
5、提高代码的可复用性
参考连接:
https://www.cnblogs.com/joemsu/p/7688307.html
推荐阅读
- 由浅入深理解AOP
- 【译】20个更有效地使用谷歌搜索的技巧
- mybatisplus如何在xml的连表查询中使用queryWrapper
- MybatisPlus|MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决
- MybatisPlus使用queryWrapper如何实现复杂查询
- SpringBoot调用公共模块的自定义注解失效的解决
- iOS中的Block
- Linux下面如何查看tomcat已经使用多少线程
- 使用composer自动加载类文件
- android|android studio中ndk的使用