@Autowired:Field injection is not recommended

目录

问题描述

常见的三种注入方式

1、filed 注入

2、构造器注入

3、setter 注入

构造器注入的优点

结论


问题描述

使用 @Autowired 时发现一个警告,Spring 团队不推荐使用 Field 注入

Field injection is not recommended

在详解里面,Spring 团队提供了构造器注入的例子。

首先介绍一下,常见的三种依赖注入方式

常见的三种注入方式

1、filed 注入

@Controller 
public class TestController { 
    @Autowired 
    private TestService testService; 

    public List<TestEntity> test() { 
        return testService.list(); 
    } 
}

这种注入方式应该是开发中最常见的注入方式,原因:

  1. 注入方式简单,加入要注入的字段,附上 @Autowired,即可
  2. 整体代码简洁明了


2、构造器注入

​​​​​@Controller
public class TestController { 
    private final TestService testService; 

    @Autowired 
    public TestController(TestService testService) {     
        this.testService = testService; 
    } 
    
     public List<TestEntity> test() { 
        return testService.list(); 
    } 
}

是 Spring4.x 版本中推荐的注入方式。这种方式看起来有些臃肿,但是别担心, lombok 提供了一个注解 @RequiredArgsConstructor(onConstructor =@_(@Autowired)),只需要将这个注解写在类上,加入要注入的字段即可(字段同样需要使用 final 定义)。这样即使注入大量依赖,代码也不会臃肿了。

@Controller 
@RequiredArgsConstructor 
public class TestController { 
    private final TestService testService; 
    
    public List<TestEntity> test() { 
        return testService.list(); 
    } 
}

3、setter 注入

@Controller 
public class TestController { 
    private TestService testService; 

    @Autowired 
    public void setTestService(TestService testService) { 
        this.testService = testService; 
    } 

    public List<TestEntity> test() { 
        return testService.list(); 
    } 
}

在 Spring3.x 刚推出的时候,推荐使用注入的是这种。Spring 官方文档:

The Spring team generally advocates setter injection, because large numbers of constructor arguments can get unwieldy, especially when properties are optional. Setter methods also make objects of that class amenable to reconfiguration or re-injection later. Management through JMX MBeans is a compelling use case.

Some purists favor constructor-based injection. Supplying all object dependencies means that the object is always returned to client (calling) code in a totally initialized state. The disadvantage is that the object becomes less amenable to reconfiguration and re-injection.

简单翻译:setter 的方式能让类在之后重新配置或者重新注入。

那么使用构造器有什么好处呢?

构造器注入的优点

Spring 文档:

The Spring team generally advocates constructor injection as it enables one to implement application components as immutable objects and to ensure that required dependencies are not null. Furthermore constructor-injected components are always returned to client (calling) code in a fully initialized state.

简单翻译:构造器注入的方式,能够保证注入的组件不可变,并且确保需要的依赖不为空。此外,构造器注入的依赖总是能够在返回客户端(组件)代码的时候保证完全初始化的状态。

总结:

  • 依赖不可变:其实说的是 final 关键字。这里简单解释一下,使用@Autowired时,@Autowired本身是单例模式,所以只会在程序启动时执行一次,即使不定义final 也不会初始化第二次,那么构造器注入时加上final,可能是为了保证程序只在启动的时候初始化一次。
  • 依赖不为空:在要实例化 TestController 时,由于自己实现了有参数的构造函数,所以不会调用默认构造函数,那么就需要Spring 容器传入所需要的参数,所以有两种情况:1、有该类型的参数传入 -> OK。2、无该类型的参数传入 -> 报错。所以保证不会为空。
  • 完全初始化的状态:这个可以跟上面的依赖不为空结合起来,向构造器传参之前,要确保注入的内容不为空,那么肯定要调用依赖组件的构造方法完成实例化。而在Java类加载实例化的过程中,构造方法是最后一步(之前如果有父类先初始化父类,然后自己的成员变量,最后才是构造方法,这里不详细展开)。所以返回来的都是初始化之后的状态。

结论

‎应尽量避免field 注入。作为替代,推荐使用构造函数或setter方法来注入依赖项。两者都有其优点和缺点,用法取决于情况。但是由于这些方法可以混合使用,因此它不是非此即彼的选择,可以将 setter 和构造函数注入组合到一个类中。构造函数更适合于强制依赖项和以不可变性为目标。setter 更适合可选依赖项。‎

参考链接:【Spring】浅谈spring为什么推荐使用构造器注入 - joemsu - 博客园

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值