IOC控制反转

IOC

        IOC,全称为Inversion of Control(控制反转),是一种设计原则,它反转了传统编程中的控制流程。在传统的编程模式中,组件之间的依赖关系是由组件自身在内部创建和维护的。而在控制反转模式中,这种依赖关系由外部容器(如Spring框架)来管理,组件不再负责自己的依赖,而是通过外部容器来注入所需的依赖。

控制反转的概念

        控制反转的核心思想是将对象的创建和它们之间的依赖关系管理从对象本身转移到外部容器。这样做的好处是:

  1. 降低耦合度:组件之间的依赖关系不再是硬编码的,因此可以更容易地更换组件实现,提高系统的灵活性和可维护性。
  2. 提高模块化:各个组件可以独立开发和测试,因为它们不依赖于具体的实现,而是依赖于抽象的接口或抽象类。
  3. 便于测试:由于组件之间的依赖被外部化,可以更容易地使用mock对象或测试桩来模拟依赖进行单元测试。

控制反转的实现方式

        控制反转可以通过以下几种方式实现:

  1. 依赖注入:这是最常见的实现方式,容器在运行时将组件所需的依赖注入到组件中。
  2. 服务定位器模式:组件不直接创建依赖,而是通过一个服务定位器来查询依赖对象。服务定位器负责管理依赖对象的创建和生命周期。
  3. 工厂模式:通过工厂类来创建对象,而不是直接在组件中创建。工厂类负责对象的创建和依赖关系的管理。

Spring框架中的IOC容器

        Spring框架是一个实现了控制反转原则的轻量级容器,它提供了一个中央容器来管理所有组件的创建、配置和依赖关系。Spring的IOC容器主要通过以下几个步骤来实现控制反转:

  1. 配置元数据:通过XML配置文件、注解或Java配置类来定义组件的元数据。
  2. 容器启动:Spring容器启动时,会读取配置元数据,并根据这些信息创建和配置组件。
  3. 依赖注入:容器根据配置的依赖关系,通过构造器注入、Setter注入等方式,将依赖注入到组件中。
  4. 应用上下文:Spring容器充当应用上下文的角色,管理所有组件的生命周期和依赖关系。
  5. 懒加载和预加载:Spring容器可以配置为懒加载(按需加载)或预加载(启动时加载)组件。

优点和缺点如下:

        优点:

  1. 解耦:组件之间的耦合度降低,提高了模块化。
  2. 可维护性:组件更容易替换和维护
  3. 可测试性:依赖可以被mock或替换,便于单元测试。
  4. 灵活性:可以灵活地配置和扩展系统

        缺点:

  1. 复杂性:引入了额外的容器和配置,增加了系统的复杂性。
  2. 性能开销:可能会有轻微的性能开销,尤其是在容器启动和依赖注入时
  3. 过度设计:在一些简单的项目中,控制反转可能被视为不必要的复杂性。

IOC实践

        控制反转(IOC)的一个典型例子是在Spring框架中使用依赖注入(DI)来管理对象的生命周期和依赖关系。下面我将通过一个简单的例子来展示IOC的使用,并在博客当中提供相应的代码。

        假设我们有一个简单的日志服务,它依赖于一个日志记录器。在传统的编程模式中,日志服务可能会自己创建日志记录器的实例。使用Spring的IOC,我们可以将日志记录器的创建和管理交给Spring容器。

代码结构与Spring应用上下文如下:

日志记录器接口和实现

public interface Logger {void log(String message);
}public class ConsoleLogger implements Logger {@Overridepublic void log(String message) {System.out.println("Logging to console: " + message);}
}

需要日志服务的业务组件

public class BusinessService {private Logger logger;// 通过构造器注入public BusinessService(Logger logger) {this.logger = logger;}public void doBusiness() {logger.log("Business operation performed.");// 执行业务逻辑}
}

配置Spring容器

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class AppConfig {@Beanpublic Logger logger() {return new ConsoleLogger();}@Beanpublic BusinessService businessService(Logger logger) {return new BusinessService(logger);}
}

启动Spring应用上下文并使用业务组件

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class Application {public static void main(String[] args) {ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);BusinessService businessService = context.getBean(BusinessService.class);businessService.doBusiness();}
}

BusinessService 需要一个 Logger 来记录日志。通过Spring的IOC容器,我们不需要在 BusinessService 中创建 Logger 的实例,而是通过配置类 AppConfig 来告诉Spring如何创建这些Bean,以及它们之间的依赖关系。当 Application 类启动时,它创建了一个Spring应用上下文,从中获取 BusinessService 的实例,并调用它的 doBusiness 方法。Spring容器负责注入Logger 的实例到 BusinessService 中,这样就实现了控制反转。

结论

        控制反转是一种重要的设计原则,它通过将控制权从组件转移到外部容器,提高了系统的灵活性和可维护性。Spring框架是实现控制反转的典型例子,它提供了一个强大的I0C容器来管理组件的生命周期和依赖关系。通过使用Spring,开发者可以构建松耦合、易于测试和维护的应用程序。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/14220.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SSH 免密登录vscode 附debug 免密登录失败问题排查

SSH 免密登录vscode 附debug 关键词 :vscode ssh ssh无法免密登录 ssh免密登录失败 1 sshd 的配置文件/etc/ssh/sshd_config, 确保公钥登录开启 PubkeyAuthentication yes2 生成公钥并上传 ssh-keygen找到本地 .ssh/id_rsa.pub 将其中文本内容搞到…

PS —— 制作证件照

PS —— 制作证件照 裁剪工具魔棒工具油漆桶工具扩展画布 老是看编程,会有些疲劳,这个专栏我会放一些其他的知识,我们今天利用PS制作证件照(注意,这里一些ps的基础操作我不会很展开的去讲): 裁…

Redisson分布式Redis锁,tryLock方法详解

在 Java 中,RLock 是 Redisson 库中提供的一个分布式锁接口,用于实现基于 Redis 的分布式锁。RLock 的 tryLock 方法用于尝试获取锁,并在特定的时间内等待获取锁。 方法签名如下: boolean tryLock(long waitTime, long leaseTim…

WPF关键组件代码示例

通过一个综合示例代码,展示WPF的关键组件,包括XAML、控件、数据绑定、样式和模板以及动画。这个示例创建一个简单的WPF应用程序,包含一个文本框、按钮和列表框,实现数据绑定、自定义样式和模板,以及按钮点击后的动画效…

深入解析R语言的贝叶斯网络模型:构建、优化与预测;INLA下的贝叶斯回归;现代贝叶斯统计学方法;R语言混合效应(多水平/层次/嵌套)

目录 ①基于R语言的贝叶斯网络模型的实践应用 ②R语言贝叶斯方法在生态环境领域中的应用 ③基于R语言贝叶斯进阶:INLA下的贝叶斯回归、生存分析、随机游走、广义可加模型、极端数据的贝叶斯分析 ④基于R语言的现代贝叶斯统计学方法(贝叶斯参数估计、贝叶斯回归、…

react使用AntV

AntV使用(https://antv.antgroup.com/) import React, { useEffect } from "react"; // npm install antv/g2 import { Chart } from "antv/g2"; const Charts () > { function Ccc() { // 准备数据 const data [ { genre: …

【Linux】脚本shell script

shell是与Linux交互的基本工具 shell script是针对shell所写的脚本,解释执行,无需编译 注意事项 指令的执行是从上而下、从左而右的分析与执行; 指令、选项与参数间的多个空白都会被忽略掉; 空白行也将被忽略掉,并且…

抽象工厂模式(AbstractFactoryPattern)

文章目录 1.抽象工厂模式定义2.UML类图3.抽象工厂模式具体实现工厂模式实现单一产品族抽象工厂实现多产品族产品类工厂类使用 4.抽象工厂模式优缺点 1.抽象工厂模式定义 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。 工厂方法模式是单一产…

2024电工杯B题食谱评价与优化模型思路代码论文分析

2024年电工杯数学建模竞赛B题论文和代码已完成,代码为B题全部问题的代码,论文包括摘要、问题重述、问题分析、模型假设、符号说明、模型的建立和求解(问题1模型的建立和求解、问题2模型的建立和求解、问题3模型的建立和求解)、模型…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-17讲 定时器按键消抖

前言: 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM(MX6U)裸机篇”视频的学习笔记,在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

计算机网络安全控制技术

1.防火墙技术 防火墙技术是近年来维护网络安全最重要的手段,但是防火墙不是万能的,需要配合其他安全措施来协同 2.加密技术 目前加密技术主要有两大类:对称加密和非对称加密 3.用户识别技术 核心是识别网络者是否是属于系统的合法用户 …

【设计模式深度剖析】【1】【结构型】【代理模式】| 玩游戏打怪、升级为例加深理解

👈️上一篇:创建型设计模式对比 | 下一篇:装饰器模式👉️ 目 录 代理模式定义英文原话直译如何理解? 3个角色UML类图1. 抽象主题(Subject)角色2. 代理类:代理主题(Proxy Subject&#xff0…

UE5 OnlineSubsystem Steam创建会话失败解决方法

连接上Steam但是创建会话失败 解决方法 在DefaultEngine.ini中加上bInitServerOnClienttrue,这个其实在官方文档里用注释给出了,直接取消注释就行 删除项目目录中的Saved、Internmediate、Binaries目录 右键你的项目.uproject选择Generate Visual Studio project f…

ASP.Net MVC在控制台添加视图时没有模型类并且不能添加视图

情况如下: 解决方法: 1.查看vs能否创建asp.net mvc项目,这种情况一般是更换了vs打开老项目 2.点击跳转至修改安装选项界面 3.选择安装项即可 如果以上都有: 看看你的视图文件是否存在在项目中 也不能点击添加,如果…

探索数值分析的奥秘:掌握NumPy与Pandas基础

新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一、NumPy:数值计算的效率提升器 二、Pandas:数据处理与分析的利器 …

Linux文本三剑客之sed

set的定义: sed是一种流编辑器,流编辑器会在编辑器处理数据之前基于预先提供的一组规则来编辑数据流。 sed编辑器可以根据命令来处理数据流中的数据,这些命令要么从命令行中输入,要么存储在一个命令文本文件中。 sed的执行过程&a…

Nextjs 动态路由获取参数

目录 一、创建page目录下的路由文件 二、通过useRouter来获取动态参数 先看官方文档:Routing: Dynamic Routes | Next.js 使用Nextjs13版本参考官方文档后实现仍有问题,网上的材料大多和官网一致,经过测试后,我找到了这个解决方…

【日记】今天好困(407 字)

正文 4T 硬盘降价了,好心动。虽然只降了 10 块钱……. 为什么硬盘这么贵啊!哼。 柜面上杂事好多。虽然一天到晚见不到几个客户,但杂事就是很多。一个头两个大。也不知道从哪儿冒出来的这么多事。 芒果干到了!还没去取,…

sql把一个表的某几列的数据存到另一个表里

一.如何用slq语句把一个表中的某几个字段的数据插入到另一个新表中,就要用下面这条slq语句: insert into 表名1(字段1,字段2) select 字段1,字段2 from 表名2 这里有一点值得注意的是这2个字段要一一对应,并且按顺序。 二.如果另一个表是…

JAVASE之类和对象(1)

路虽远,行则将至;事虽难,做则必成。 主页:趋早——Step 专栏:JAVASE gitte:https://gitee.com/good-thg 引言: 这篇文章我们只介绍前半部分,下一篇文章会介绍剩下的部分。 目录 一、…