Intro to Inversion of Control and Dependency Injection with Spring

news/2024/7/24 12:42:57 标签: spring, java, 前端

What Is Inversion of Control?

Inversion of Control is a principle in software engineering which transfers the control of objects or portions of a program to a container or framework.

在 Spring 中,类的实例化、依赖的实例化、依赖的传入都交由 Spring Bean 容器控制, 而不是用new方式实例化对象再通过非构造函数方法传入依赖等常规方式。 实质的控制权已经交由程序管理,而不是程序员管理,所以叫做控制反转。

We can achieve Inversion of Control through various mechanisms
such as:

  • Strategy design pattern,
  • Service Locator pattern,
  • Factory pattern,
  • Dependency Injection (DI).

What Is Dependency Injection?

Dependency injection is a pattern we can use to implement IoC.

Connecting objects with other objects, or “injecting” objects into other objects, is done by an assembler rather than by the objects themselves.

Spring 启动时会把所需的类实例化成对象,如果需要依赖,则先实例化依赖,然后实例化当前类。 因为依赖必须通过构建函数传入,所以实例化时,当前类就会接收并保存所有依赖的对象。 这一步也就是所谓的依赖注入。

Here’s how we would create an object dependency in traditional programming:

public class Store {
    private Item item;
 
    public Store() {
        item = new ItemImpl1();    
    }
}

By using DI, we can rewrite the example.

public class Store {
    private Item item;
    public Store(Item item) {
        this.item = item;
    }
}

The Spring IoC Container

In the Spring framework, the interface ApplicationContext represents the IoC container. The Spring container is responsible for instantiating, configuring and assembling objects known as beans, as well as managing their life cycles.

Dependency Injection in Spring can be done through constructors, setters or fields.


Constructor-Based Dependency Injection

In the case of constructor-based dependency injection, the container will invoke a constructor with arguments each representing a dependency we want to set.

Let’s see the configuration of a bean and its dependencies using annotations:


public class AppConfig {

    
    public Item item1() {
        return new ItemImpl1();
    }

    
    public Store store() {
        return new Store(item1());
    }
}

We use the @Bean annotation on a method to define a bean. If we don’t specify a custom name, then the bean name will default to the method name.

Another way to create the configuration of the beans is through XML configuration:

<bean id="item1" class="org.baeldung.store.ItemImpl1" /> 
<bean id="store" class="org.baeldung.store.Store"> 
    <constructor-arg type="ItemImpl1" index="0" name="item" ref="item1" /> 
</bean>

Setter-Based Dependency Injection

For setter-based DI, the container will call setter methods of our class after invoking a no-argument constructor or no-argument static factory method to instantiate the bean.Let’s create this configuration using annotations:


public Store store() {
    Store store = new Store();
    store.setItem(item1());
    return store;
}

We can also use XML for the same configuration of beans:

<bean id="store" class="org.baeldung.store.Store">
    <property name="item" ref="item1" />
</bean>

We can combine constructor-based and setter-based types of injection for the same bean. The Spring documentation recommends using constructor-based injection for mandatory dependencies, and setter-based injection for optional ones.

Field-Based Dependency Injection

In case of Field-Based DI, we can inject the dependencies by marking them with an @Autowired annotation:

public class Store {
    
    private Item item; 
}

While constructing the Store object, if there’s no constructor or setter method to inject the Item bean, the container will use reflection to inject Item into Store.


Autowiring Dependencies

There are four modes of autowiring a bean using an XML configuration:

  • no: the default value – this means no autowiring is used for the bean and we have to explicitly name the dependencies.
  • byName: autowiring is done based on the name of the property, therefore Spring will look for a bean with the same name as the property that needs to be set.
  • byType: similar to the byName autowiring, only based on the type of the property. This means Spring will look for a bean with the same type of the property to set. If there’s more than one bean of that type, the framework throws an exception.
  • constructor: autowiring is done based on constructor arguments, meaning Spring will look for beans with the same type as the constructor arguments.

参考:
Intro to Inversion of Control and Dependency Injection with Spring


http://www.niftyadmin.cn/n/152049.html

相关文章

react源码解析16.concurrent模式

concurrent mode react17支持concurrent mode&#xff0c;这种模式的根本目的是为了让应用保持cpu和io的快速响应&#xff0c;它是一组新功能&#xff0c;包括Fiber、Scheduler、Lane&#xff0c;可以根据用户硬件性能和网络状况调整应用的响应速度&#xff0c;核心就是为了实…

JIRA学习

概念 史诗。行业内&#xff0c;一个大功能模块&#xff0c;视为一个史诗&#xff1b; 故事。每个功能点&#xff0c;视为一个故事&#xff1b; 冲刺sprint。一个冲刺为一个迭代周期&#xff0c;其长度&#xff0c;取决于项目组的节奏&#xff1b; 原则与规范 一个项目一个史…

Maven的安装与配置

目录 一、安装本地Maven下载 Maven官网下载 下载完成后&#xff0c;选择一个路径进行解压 配置path环境变量 验证安装是否成功 二、配置settings文件 1. 修改mirror 2. 修改jdk 一、安装本地Maven下载 Maven官网下载 下载完成后&#xff0c;选择一个路径进行解压 记住…

【22】Verilog进阶 - 序列检测【STG变精通】

VL25 输入序列连续的序列检测 本题并不难【中等】难度给高了 【做题关键】 (1)需要使用移位寄存器的思路。其实reg型是寄存器,也可以当做是移位寄存器,重要的是对其的处理,使用的是移位寄存器的思路 (2)注意新移入数据存放在低位 1 题目 + 代码 + TestBench 很简单,没…

scratch消灭病毒 电子学会图形化编程scratch等级考试三级真题和答案解析2022年12月

目录 scratch消灭病毒 一、题目要求 1、准备工作 2、功能实现 二、案例分析

RabbitMQ的几种交换机类型

1.Direct exchange&#xff08;直连交换机&#xff09; 直连型交换机&#xff08;direct exchange&#xff09;是根据消息携带的路由键&#xff08;routing key&#xff09;将消息投递给对应队列。2.Fanout exchange&#xff08;扇型交换机&#xff09; 扇型交换机&…

【华为机试真题详解 Python实现】去除多余空格【2023 Q1 | 100分】

文章目录 前言题目描述输入描述输出描述示例 1解题思路参考代码前言 《华为机试真题详解》专栏含牛客网华为专栏、华为面经试题、华为OD机试真题。 如果您在准备华为的面试,期间有想了解的可以私信我,我会尽可能帮您解答,也可以给您一些建议! 本文解法非最优解(即非性能…

订单如何自动取消?延迟队列?定时任务?

文章目录 DelayQueue案例实现原理Timer实现原理ScheduledThreadPoolExecutor实现原理RocketMQ案例实现原理RabbitMQ案例监听Redis过期key任务存在延迟丢消息太频繁消息消费只有广播模式Netty的HashedWheelTimer实现原理Hutool的SystemTimer