Spring依赖注入DI之三种依赖注入类型详解

 更新时间:2023年09月13日 09:04:27   作者:黄泥川水猴子  
这篇文章主要介绍了Spring依赖注入DI之三种依赖注入类型详解,通过 @Autowired 注解,字段注入的实现方式非常简单而直接,代码的可读性也很强,事实上,字段注入是三种注入方式中最常用、也是最容易使用的一种,需要的朋友可以参考下

 Spring依赖注入

在这里插入图片描述

字段注入

首先,我们可以使用字段注入。想要在一个类中通过字段的形式注入某个对象,可以采用这样的方式:

public class ClientService { 
    @Autowired 
    private HealthRecordService healthRecordService; 
    public void recordUserHealthData() { 
        healthRecordService.recordUserHealthData(); 
    } 
}

可以看到,通过 @Autowired 注解,字段注入的实现方式非常简单而直接,代码的可读性也很强。事实上,字段注入是三种注入方式中最常用、也是最容易使用的一种。但它也是三种注入方式中最应该避免使用的。就像开篇说的,我们在 IDEA 中使用字段注入时会遇到“Field injection is not recommended”的提示。你知道为什么吗?原因有三点。

问题一、

字段注入的最大问题是对象的外部可见性。在前面的 ClientService 类中,我们通过定义一个私有变量 HealthRecordService 来注入该接口的实例。显然,这个实例只能在 ClientService 类中被访问,脱离了容器环境我们无法访问这个实例,来看下面这段代码:

ClientService clientService = new ClientService(); 
clientService.recordUserHealthData (); 

执行这段代码的结果就是抛出一个 NullPointerException 空指针异常,原因就在于无法在 ClientService 的外部实例化 HealthRecordService 对象。采用字段注入,类与容器的耦合度过高,我们无法脱离容器来使用目标对象。如果编写测试用例来验证 ClientService 类的正确性,那么想要使用 HealthRecordService 对象,就只能使用反射的方式,这种做法实际上是不符合 JavaBean 开发规范的,而且可能一直无法发现空指针异常的存在。

问题二、

我们无法设置需要注入的对象为 final,也无法注入那些不可变对象,final类型的变量在调用class的构造函数的这个过程当中就得初始化完成,这个是基于字段的依赖注入做不到的地方,只能使用基于构造函数的依赖注入的方式.

问题三、

字段注入的第三个问题是可能导致潜在的循环依赖,即两个类之间互相进行注入,例如下面这段示例代码:

public class ClassA { 
    @Autowired 
    private ClassB classB; 
} 
public class ClassB { 
    @Autowired 
    private ClassA classA; 
} 

这里的 ClassA 和 ClassB 发生了循环依赖。上述代码在 Spring 中是合法的,容器启动时并不会报任何错误,而只有在使用到具体某个 ClassA 或 ClassB 时才会报错。

问题四、

无法对注入的属性进行安全检查 在程序启动的时候无法拿到这个类,只有在真正的业务使用的时候才会拿到,若注入的是null,因为不调用将一直无法发NullPointException的存在。 或者想在属性注入的时候,增加验证措施,也无法办到。

基于以上四点,无论是 IDEA,还是 Spring 官方,都不推荐开发人员使用字段注入这种注入模式,而是推荐构造器注入。

在面试中,针对字段注入,请记住它主要的三点缺陷:不具备外部可见性、会导致循环依赖,以及无法注入不可变对象

构造器注入

@Controller
@RequestMapping("employee")
public class EmployeeController {
    private final EmployeeMapper employeeMapper;
    @Autowired
    public EmployeeController(EmployeeMapper employeeMapper) {
        this.employeeMapper = employeeMapper;
    }
}

优点:

  • 保证依赖不可变(final关键字)。
  • 保证依赖不为空(省去了我们对其检查)。
  • 保证返回客户端(调用)的代码的时候是完全初始化的状态。
  • 避免了循环依赖。
  • 提升了代码的可复用性。
  • 可以明确成员变量的注入顺序。

缺点:

  • 当注入参数较多时,代码臃肿。

set方法注入

@Controller
@RequestMapping("employee")
public class EmployeeController {
    private EmployeeMapper employeeMapper;
    @Autowired
    public void setEmployeeMapper(EmployeeMapper employeeMapper) {
        this.employeeMapper = employeeMapper;
    }
}

优点:

  • 相比构造器注入,set注入类似于选择性注入。
  • 允许在类构造完成后重新注入。

缺点: 暂无

到此这篇关于Spring依赖注入DI之三种依赖注入类型详解的文章就介绍到这了,更多相关Spring依赖注入内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 解析SpringBoot自定义参数校验注解

    解析SpringBoot自定义参数校验注解

    这篇文章主要介绍了SpringBoot自定义参数校验注解,引入依赖,spring validation是在hibernate-validator上做了一层封装,文中提到了定义参数校验注解与处理器的示例代码,感兴趣的朋友跟随小编一起看看吧
    2023-10-10
  • java使用itext如何直接生成pdf

    java使用itext如何直接生成pdf

    在工作中,制作PDF文件是常见需求,尤其是需要插入动态数据或图像时,使用PDF模板填充表单域通常足够,但对于复杂文件,可以通过拼接PDF内容来灵活排版,iText库提供了丰富的PDF操作功能,如设置页面大小、边距、字体、生成动态表格、添加水印、设置密码等
    2024-09-09
  • Java中Session的详解

    Java中Session的详解

    这篇文章主要介绍了了解java中的session的相关问题,什么是session,session怎么用等,具有一定参考价值,需要的朋友可以了解下。
    2021-10-10
  • Java使用Socket通信传输文件的方法示例

    Java使用Socket通信传输文件的方法示例

    这篇文章主要介绍了Java使用Socket通信传输文件的方法,结合实例形式分析了java socket编程实现文件传输操作的相关技巧,需要的朋友可以参考下
    2017-06-06
  • java 非对称加密算法RSA实现详解

    java 非对称加密算法RSA实现详解

    这篇文章主要介绍了java 非对称加密算法RSA实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-07-07
  • Redis框架Jedis及Redisson对比解析

    Redis框架Jedis及Redisson对比解析

    这篇文章主要介绍了Redis框架Jedis及Redisson对比解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • Spring Gateway自定义请求参数封装的实现示例

    Spring Gateway自定义请求参数封装的实现示例

    这篇文章主要介绍了Spring Gateway自定义请求参数封装的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • Spring Boot使用AOP实现REST接口简易灵活的安全认证的方法

    Spring Boot使用AOP实现REST接口简易灵活的安全认证的方法

    这篇文章主要介绍了Spring Boot使用AOP实现REST接口简易灵活的安全认证的方法,非常具有实用价值,需要的朋友可以参考下
    2018-11-11
  • 详细讲解Java的泛型

    详细讲解Java的泛型

    这篇文章主要介绍了Java的泛型,是Java入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09
  • java实现快速打字游戏

    java实现快速打字游戏

    这篇文章主要为大家详细介绍了java实现快速打字游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07

最新评论