Springboot中依赖注入的三种方式详解

 更新时间:2023年09月13日 08:46:30   作者:五月天的尾巴  
这篇文章主要介绍了Springboot中依赖注入的三种方式详解,Setter Injection需要依赖@Autowired注解,使用方式与Field Injection有所不同,Field Injection时@Autowired是用在成员变量上,需要的朋友可以参考下

Springboot依赖注入Bean的方式

一、Field 注入/属性注入

@Autowired注解的一大使用场景就是Field Injection。

@Controller
public class UserController {
    @Autowired
    private UserService userService;
}

通过Java的反射机制实现,所以private的成员也可以被注入具体的对象

优点

  • 代码少,简洁明了。
  • 新增依赖十分方便,不需要修改原有代码

缺点

  • 容易出现空指针异常。Field 注入允许构建对象实例时依赖的对象为空,导致空指针异常不能在启动时就爆出来,只能在用到它时才发现。
    空指针异常不是必现的,与bean的实例化顺序有关。有时,把依赖的bean改个名字就会报空指针异常。
  • 会出现循环依赖的隐患。

二、set注入

Setter Injection需要依赖@Autowired注解,使用方式与Field Injection有所不同,Field Injection时@Autowired是用在成员变量上,而Setter Injection的时候,@Autowired是用在成员变量的Setter函数上。

@Controller
public class UserController {
    private UserService userService;
    @Autowired
    public void setUserService(UserService userService){
        this.userService = userService;
    }
}

通过调用成员变量的set方法来注入想要使用的依赖对象。

优点

  • 注入参数多的时候比较方便。构造器注入参数太多了,显得很笨重
  • 能让类在之后重新配置或者重新注入。

缺点

  • 有一定风险。set注入是后初始化其依赖对象,如果一个对象在没有完全初始化就被外界使用是不安全的(尤其是在多线程场景下更加突出)。

三、构造器注入

Constructor Injection是构造器注入,是Springboot最为推荐的一种使用方式。

@Controller
public class UserController {
    private final UserService userService;
    public UserController(UserService userService){
        this.userService = userService;
    }
}

注意:

  • 不能提供无参构造方法,否则Springboot默认会加载无参的构造方法,Bean实例对象会为null
  • Springboot官方建议使用final来修饰成员变量,然后通过构造方法来进行注入。原因:final修饰的成员变量是不能够被修改的;不加final虽然也能注入Bean,但是若被其他人修改为null,可能会导致不必要的问题,所以最好是加final。

通过对象构建的时候建立关系,这种方式对对象创建的顺序会有要求,当然Spring会为你搞定这样的先后顺序,除非你出现循环依赖,然后就会抛出异常。

Spring 4.x 的时候,Spring 官方在对比构造器注入和 Setter 注入时,推荐使用构造器注入方式:

优点

  • 保证注入的组件不可变
  • 确保需要的依赖不为空
  • 解决循环依赖的问题(若有循环依赖会在项目启动时抛错)

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

若手工写构造方法觉得麻烦,也可以使用lombok中的@RequiredArgsConstructor

@RequiredArgsConstructor
public class VerifyController {
    private final UserService userService;
    private final StudentService studentService;
}

@RequiredArgsConstructor

@RequiredArgsConstructor 注解是针对标有 @NonNull 注解的变量和 final 变量进行参数的构造方法。

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

相关文章

  • Java中==与equals()及hashcode()三者之间的关系详解

    Java中==与equals()及hashcode()三者之间的关系详解

    最近也是在读Hollis的《深入理解Java核心技术》里面一节讲到了equals()和hashcode()的关系,对于这个高频面试点,咱们需要认真理清一下几者之间的关系
    2022-10-10
  • 全面解析Spring Security 过滤器链的机制和特性

    全面解析Spring Security 过滤器链的机制和特性

    这篇文章主要介绍了Spring Security 过滤器链的机制和特性,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • Java字符串定义及常用方法

    Java字符串定义及常用方法

    这篇文章主要介绍了Java字符串定义及常用方法,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-08-08
  • 详解使用Java原生代理实现AOP实例

    详解使用Java原生代理实现AOP实例

    本篇文章主要介绍了详解使用Java原生代理实现AOP实例,具有一定的参考价值,有兴趣的可以了解一下。
    2017-01-01
  • Spring AOP概念及原理解析

    Spring AOP概念及原理解析

    这篇文章主要介绍了Spring AOP概念及原理 ,通过使用 Spring AOP 实现日志管理,我们可以将日志记录的逻辑从业务逻辑中分离出来,简化了代码的维护,需要的朋友可以参考下
    2024-07-07
  • MybatisX中xml映射文件中命名空间爆红的解决

    MybatisX中xml映射文件中命名空间爆红的解决

    本文主要介绍了MybatisX中xml映射文件中命名空间爆红的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • 解决fcitx输入法在IDEA中输入法候选框无法跟随光标移动的问题

    解决fcitx输入法在IDEA中输入法候选框无法跟随光标移动的问题

    这篇文章主要介绍了解决fcitx输入法在Intellij IDEA开发工具中输入法候选框无法跟随光标移动的问题,代码简单易懂对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • Spring Boot整合 NoSQL 数据库 Redis详解

    Spring Boot整合 NoSQL 数据库 Redis详解

    这篇文章主要为大家介绍了Spring Boot整合 NoSQL 数据库 Redis详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • sprng和struts有什么区别?

    sprng和struts有什么区别?

    Spring和Struts都是近年来比较流行的框架,Struts主要用于表示层,Spring用于业务层,以及Hiberate主要用于持久层,
    2015-06-06
  • Java中双冒号(::)运算操作符用法详解

    Java中双冒号(::)运算操作符用法详解

    这篇文章主要给大家介绍了关于Java中双冒号(::)运算操作符用法的相关资料,双冒号运算操作符是类方法的句柄,lambda表达式的一种简写,这种简写的学名叫eta-conversion或者叫η-conversion,需要的朋友可以参考下
    2023-11-11

最新评论