Spring的三种依赖注入的方式

spring · 浏览次数 : 147

小编点评

依赖注入(Dependency Injection,简称DI)和控制反转(Inversion of Control,简称IOC)是Spring框架中的核心概念,它们有助于降低代码间的耦合度,提高系统的可维护性和可扩展性。 依赖注入是通过将对象的依赖关系从代码中抽离出来,由其他(类,第三方容器)来管理的一种技术。控制反转则是指,这种依赖关系不再由代码直接操控了,而是交由其他(类,第三方容器)来管理。 依赖注入有以下三种常见的实现方式: 1. 构造函数注入:通过在构造函数中传入依赖对象,完成对象的初始化工作。优点是可以注入不可变对象,且注入对象会被完全初始化,通用性较好。缺点是当需要依赖的对象过多时,构造函数会变得臃肿。 2. setter方法注入:在JavaBean中,通过setXXX()和getXXX()方法来访问和设置依赖对象的属性。优点是符合单一职责的设计原则,因为每个Setter只针对一个对象。缺点是不能注入不可变对象(final修饰的对象),且注入的对象可以被修改。 3. 属性注入:在bean的变量上使用注解进行依赖注入。优点是使用简单。缺点是不能注入不可变对象(final修饰的对象),且只能适应于IoC容器。 在实际开发中,根据不同的场景和需求选择合适的注入方式。简单来说,对于必须的依赖,可以使用构造器注入;对于可选的依赖或可变的依赖,可以使用setter方法注入。但在日常开发中,属性注入是最常用且最直观的方式。

正文

1、什么是依赖注入

依赖注入(Dependency Injection,简称DI),是IOC的一种别称,用来减少对象间的依赖关系。
提起依赖注入,就少不了IOC。
IOC(Inversion of Control,控制反转)是一种设计思想,它将原本在程序中手动创建对象的控制权,交由Spring框架来管理。

IOC和DI,是同一个概念的不同角度描述。(IOC是一种思想,DI则是该思想的一种具体的技术实现方案。)
也可以这么理解:
IOC是目的(目的是创建对象),DI是手段(通过什么手段获取外部对象)。

2、依赖注入的常见实现方式

  • 构造函数注入
  • setter方法注入
  • 属性注入

2.1 构造函数注入

将各个必需的依赖全部放在带有注解构造方法的参数中,并在构造方法中完成对应变量的初始化,这种方式,就是基于构造方法的注入。

@RestController
public class UserController {
    // 构造方法注入
    private UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }

    @RequestMapping("/add")
    public UserInfo add(String username, String password) {
        return userService.add(username, password);
    }
}

该方式的优点:

  • 可注入不可变对象
  • 注入对象不会被修改
  • 注入对象会被完全初始化
  • 通用性更好

该方式的缺点:

  • 当需要依赖的对象过多,构造方法会臃肿

2.2 setter方法注入

在JavaBean中,通常会通过setXXX()和getXXX()方法来访问对应属性。
这些setXXX()方法统称为setter方法,getXXX()方法统称为getter方法。
通过setter方法,可以更改相应的对象属性,通过getter方法,可以获得相应属性的状态。

所以,当前对象只要为其依赖对象所对应的属性添加setter方法,就可以通过setter方法将相应的依赖对象设置到被注入对象中。

@Service
public class UserService {
	
    private SmsService smsService;
    
    @Autowired  //通过setter方法实现注入
    public void setWolf3Bean(SmsService smsService) {
        this.smsService = smsService;
    }
}

该方式的优点:

  • 完全符合单一职责的设计原则,因为每一个 Setter 只针对一个对象

该方式的缺点:

  • 不能注入不可变对象(final 修饰的对象)
  • 注入的对象可被修改

2.3 属性注入

属性注入,就是在bean的变量上使用注解进行依赖注入。

属性注入是我们最熟悉的,也是日常开发中使用最多的一种注入方式,它的实现代码如下:

@RestController
public class UserController {
    // 属性对象
    @Autowired
    private UserService userService;

    @RequestMapping("/add")
    public UserInfo add(String username, String password) {
        return userService.add(username, password);
    }
}

该方式的优点:

  • 使用简单

该方式的缺点:

  • 不能注入不可变对象(final 修饰的对象)
  • 注入的对象可被修改
  • 只能适应于 IoC 容器

3、总结

在实际开发中,根据不同的场景,选择不同的注入方式。
简单来说,就是

  • 强制依赖就用构造器方式
  • 可选、可变的依赖就用setter注入

但,日常开发应该还是属性注入较多~

与Spring的三种依赖注入的方式相似的内容:

Spring的三种依赖注入的方式

1、什么是依赖注入 依赖注入(Dependency Injection,简称DI),是IOC的一种别称,用来减少对象间的依赖关系。 提起依赖注入,就少不了IOC。 IOC(Inversion of Control,控制反转)是一种设计思想,它将原本在程序中手动创建对象的控制权,交由Spring框架来

Java面试题:Spring中的循环依赖,给程序员带来的心理阴影

循环依赖通常发生在两个或多个Spring Bean之间,它们通过构造器、字段(使用@Autowired)或setter方法相互依赖,从而形成一个闭环。Spring通过三级缓存机制、@Lazy注解以及避免构造器循环依赖等方式来解决循环依赖问题。这些机制使得Spring容器能够更加灵活地处理bean之间...

[转帖]Spring Cloud 整合 SkyWalking

https://www.jianshu.com/p/e81e35dc6406 Java Agent 服务器探针 探针,用来收集和发送数据到归集器。参考官网给出的帮助 Setup java agent,我们需要使用官方提供的探针为我们达到监控的目的,按照实际情况我们需要实现三种部署方式 IDEA 部署

Spring MVC 获取三个域(request请求域,session 会话域,application 应用域)对象的方式

1. Spring MVC 获取三个域(request请求域,session 会话域,application 应用域)对象的方式 @目录1. Spring MVC 获取三个域(request请求域,session 会话域,application 应用域)对象的方式2. Servlet中的三个域对象3

Java基础:线程的三种创建方式

一、继承Thread类 定义一个类继承线程类Thread 重写run()方法 创建线程对象 调用线程对象的start()方法创建线程 Thread类的常用API setName(String name):给线程取名字 getName():获取线程的名字 public static Thread cu

【Spring Cloud】Eureka缓存机制

Eureka分为Client端和Server端,Client端向Server端注册自己的服务信息,并且拉取所有服务的注册信息,Server端作为注册中心,负责接收Client端的注册信息,维护所有服务的注册信息,Server端也可以开启集群模式,相互之间同步服务的注册信息。 与缓存相关的三个变量 1

[转帖]给你的SpringBoot做埋点监控--JVM应用度量框架Micrometer

https://www.cnblogs.com/yunlongn/p/11343848.html 这世上有三样东西是别人抢不走的:一是吃进胃里的食物,二是藏在心中的梦想,三是读进大脑的书 JVM应用度量框架Micrometer实战 前提 spring-actuator做度量统计收集,使用Promet

用现代C++写一个python的简易型list

std::variant介绍:en.cppreference.com/w/cpp/utility/variant 通过泛型模板(仅提供了int, double, string三种类型的存储),实现了append, pop, front, back, size等方法,并且通过重载运算符实现了对负数索引

浅谈字节码增强技术系列2-Asm与Cglib

作者:董子龙 前言 记得那是2022年秋天的第一场雨,比2021年来的稍晚一些,在那个秋雨朦胧的下午,正在工位上奋笔疾书的我突然听到了前面波哥对着手机听筒说出来的"温柔"的话语:说说你了解的spring-aop。话音刚落,aop这三个字便犹如一把利剑一样狠狠的扎到了我的心上,让我的脑海中顿时浮现了当

我的第一个项目(三):注册登陆功能(后端)

好家伙,前端出了点bug 我们来搞定后端先: 后端我们用的框架是Spring boot 数据库:MySQl 代码已开源,连接在最后 新建项目: 只点Java Web 项目目录如下: 1.首先,我们在pom.xml文件中导入第三方包: web服务,mysql连接驱动等一系列包 pom.xml文件: <