3. IoC 与DI

一、 定义

  • IoC,即控制反转,把对象的调用权交给容器,通过容器来实现对象的装配和管理。
  • DI,即依赖注入,对象之间依赖关系由容器在运行期决定,由容器动态的将依赖关系注入到对象之中。
  • DI,是对IoC更完善的描述。

二、 疑问

  • 谁依赖谁?【对象实例化依赖容器】
  • 为什么要依赖?【对象实例化通过容器自动得到外部依赖】
  • 谁注入谁?【容器注入对象的依赖到对象中】
  • 注入了什么?【注入了对象的外部依赖】

三、 Hyperf的依赖注入的实现

  • 由hyperf/di 组件提供功能支持
  • 更符合长生命周期的应用使用
  • 提供了 注解、注解注入、AOP
  • 基于 PSR-11 实现,可独立应用于其它框架

四、注入方式

  • 通过构造方法注入
  • 通过#[Inject]注解注入

五、 注入类型

  • 简单对象注入
  • 抽象对象注入
  • 工厂对象注入

六、 实例

① 【简单对象注入】

  • 假设存在一个UserService类,在IndexController类中引用它
<?php
// UserService类
namespace App\Service;
class UserService {public fucntion getInfoById(int $id) {// 假设存在一个 Info  实体return (new Info())-> fill($id);} 
}

1. 构造函数的形式

构造函数定义依赖类的 Typehint
IndexController 在被DI容器创建时,会自动注入相关依赖

<?php
// IndexController
namespace App\Controller;
class IndexController {private $userService;public function __construct(UserService $userService) {$this->userService = $userService;}public function index() {return $this->userService->getInfoById(1);}
}

2. Inject注解的形式

在类成员属性上定义 #[Inject] 注解 和 @var,完成依赖注入

<?php
namespace App\Controller;
use App\Service\UserSerice;
use Hyperf\Di\Annotation\Inject;
class IndexController {#[Inject]private UserService $userService;public function index() {return $this->userService->getInfoById(1);}
}

②【抽象对象注入】

1. 定义一个接口类 UserServiceInterface

UserService 实现接口类

<?php
namespace App\Service;// UserServiceInterface 接口类
interface UserServiceInterface {public function getInfoById(int $id);
}// UserService 实现类
class UserService implements UserServiceInterface {public function getInfoById(int $id) {return (new Info())->fill($id);}
}

2. 在对应的位置,进行 接口类 与 实现类 的关系绑定

<?php
// 在 config/dependencies.php 内
use App\Service\UserServiceInterface;
use App\Service\UserService;
return ['dependencies' => [UserServiceInterface::class =>UserService::class,],
];

3. 通过以接口类作为 Typehint 注入对应的实现类

<?php
namespace App\Controller;use App\Service\UserServiceInterface;
use Hyperf\Di\Annotation\Inject;class IndexController {/*** @var UserServiceInterface*/#[Inject]private $userService;public function index() {return $this-<userService->getInfoById(1);}
}

③【工厂对象注入】

  • 通过容器来创建一个复杂类,如构造函数需要接收参数的,参数应是应用参数,而不是动态的请求参数。

  • DI管理的对象是单例

    <?php
    namespace App\Service;class UserService inplements userServiceInterface {private $enableCache;public function __construct(bool $enableCache) {$this->enableCache = $enableCache;}public function getInfoById(int $id) {return (new Info())->fill($id);}
    }
    
  • 通过工厂类创建复杂的对象

    • 定义一个工厂类,在__invoke()方法内实现对象的创建并返回
    • make() 函数创建短声明周期对象
    <?php
    namespace App\Service;
    use Hyperf\Contract\ConfigInterface;
    use Psr\Container\ContainerInterface;class UserServiceFactory {// __invoke() 方法写成对象的生产// 方法参数会自动注入一个当前的容器实例// 通过$container对象可以取出hyperf\Di容器中的任意对象public function __invoke(ContainerInterface $container) {$config = $container->get(ConfigInterface::class);// 假设对应的配置的 key 为 cache.enable$enableCache = $config->get('cache.enable', false);// make(string $name, array $parameters=[]) 方法 等同于 new,使用 make() 方法是为了允许 AOP 的介入,而直接 new 会导致 AOP 无法正常介入流程return make(UserService::class, compact('enableCache'));}
    }
    
  • 调整接口类与工厂类的关系,注入的即为 由工厂类创建的对象

    <?php
    // 在 config/dependencies.php 内
    use App\Service\UserServiceInterface;
    use App\Service\UserServiceFactory;
    return ['dependencies' => [UserServiceInterface::class =>UserServiceFactory::class,],
    ];
    

④ 注入容器自身

  • 直接注入 Psr\Container\ContainerInterface
  • 通过 Hyperf\Utils\ApplicationContext::getContainer() 获得

七、 注解 和 DI 的总结

  1. 注解只是元数据定义,实现功能时不利用这些数据的话,没有任何作用。
  2. 使用了注解的对象,必须基于 Hyperf 和 DI容器来创建对象才能生效。
  3. 注解可以用在类、类方法、类成员属性上。
  4. DI容器是负责管理 对象的创建对象的依赖管理 的。
  5. DI容器创建出来的对象是个单例,是长生命周期对象。
  6. 通过 $container->make() 方法 或 make() 函数创建短生命周期对象。
  7. 通过 new 来实例化的对象注解 不会生效,依赖需自行管理。

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

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

相关文章

万户ezEIP企业管理系统 productlist.aspx SQL注入漏洞复现

0x01 产品简介 万户ezEIP是一种企业资源规划软件,旨在帮助企业管理其各个方面的业务流程。它提供了一套集成的解决方案,涵盖了财务、供应链管理、销售和市场营销、人力资源等各个领域。 0x02 漏洞概述 万户ezEIP企业管理系统 productlist.aspx 接口存在SQL注入漏洞,未经身…

11_原始值的响应式方案-ref

目录 引入 ref解决响应丢失的问题自动脱 ref 引入 ref 在之前实现的 reactive 方法&#xff0c;其代理的目标必须是一个非原始值才行&#xff0c;例如&#xff1a; let str vue // 无法拦截 str 的修改 str vue3上述这个例子表达的意思就是&#xff0c;我们还缺少一个能够对…

ZYNQ:流水灯实验

实验目的 PL_LED0 和 PL_LED1 连接到 ZYNQ 的 PL 端&#xff0c;PL_LED0 和 PL_LED1循环往复产生流水灯的效果&#xff0c;流水间隔时间为 0.5s。 原理图 程序设计 本次实验是需要实现两个LED的循环熄灭点亮&#xff0c;时间间隔是0.5S,对时间间隔的控制使用计数器来完成。本…

第十九课:Python学习之继承

继承 目标 单继承多继承 面向对象三大特性 封装 根据 职责 将 属性 和 方法 封装 到一个抽象的 类 中继承 实现代码的重用&#xff0c;相同的代码不需要重复的编写多态 不同的对象调用相同的方法&#xff0c;产生不同的执行结果&#xff0c;增加代码的灵活度 01. 单继承 …

安装buildkit,并使用buildkit构建containerd镜像

背景 因为K8s抛弃Docker了,所以就只装了个containerd,这样就需要一个单独的镜像构建工具了,就用了buildkit,这也是Docker公司扶持的,他们公司的人出来搞的开源工具,官网在 https://github.com/moby/buildkit 简介 服务端为buildkitd,负责和runc或containerd后端连接干活,目前…

MySQL 查询按照更新时间排序遇到相同更新时间的会少数据

MySQL分页后出现重复数据或丢失记录的原因可能包括&#xff1a;SQL查询条件不一致、使用了不稳定的排序、LIMIT语句与ORDER BY配合问题、缓存设置不当或数据库复制配置错误。需要检查查询逻辑和系统配置以解决这些问题。 MySQL分页导致数据重复的原因&#xff1a; 1、排序算法…

如何有效维护您的WordPress在线商店内容:提高客户参与度与转化率的实用技巧

在电子商务领域&#xff0c;内容为王。新鲜、相关且有吸引力的内容能显著提升客户参与度和转化率。本文将探讨如何有效更新和维护您的在线商店内容&#xff0c;确保客户始终获得最佳体验。 定期更新产品信息 产品描述 产品描述是吸引客户和促成销售的关键。定期检查并更新产…

Netty基础原理

1.Netty概述 Netty是由JBoss提供的开源的高性能、异步事件驱动的网络应用框架&#xff0c;通过Netty可以很快的构建出通信效率极高的应用&#xff1b; 异步与同步是相对的&#xff0c;在请求或执行过程中&#xff0c;如果会阻塞等待就是同步&#xff0c;反之就是异步 1.1 Net…

vue3纯前端验证码示例

前言 验证码的用途&#xff1a;通过要求用户输入一串难以被机器自动识别的字符或图像&#xff0c;有效阻止恶意用户或脚本通过暴力破解方式尝试登录账户。验证码的分类&#xff1a;常见的验证码有短信、文本、图形等&#xff0c;安全度越高&#xff0c;依赖的插件或服务也越多…

ENSP环回路由的配置

环回路由配置如下&#xff0c;网段及其基础配置已写完。为了实现全网通&#xff0c;需要给路由器手写配置&#xff0c;使用 ip route—static目标网段下一跳。把所有情况都要考虑到&#xff0c;就会出现去往一个网段的最优路径和次优路径&#xff0c;近路和远路都能前往目标网段…

Spire.PDF for .NET【页面设置】演示:在 C# 中应用 PDF 页面转换

当您在导出为 PDF 格式的文档中翻页时&#xff0c;页面过渡会显示装饰效果&#xff0c;例如溶解或擦除。当您以 PDF 格式创建幻灯片时&#xff0c;页面过渡特别有用。Spire.PDF是一款专为开发人员设计的强大 .NET 组件&#xff0c;可让您将页面过渡应用于 PDF 文件。 这里介绍…

【新专栏】Excel数据分析与模拟决策

专栏入口&#xff1a;Excel数据分析与模拟决策 主要面向使用Excel的用户&#xff0c;讲解Excel的数据分析&#xff0c;模拟分决策内容&#xff0c;内容涵盖基于Excel的统计分析&#xff0c;数据生成&#xff0c;采样&#xff0c;假设检验&#xff0c;线性回归&#xff0c;线性规…

大语言模型(LLM)入门级选手初学教程

链接&#xff1a;https://llmbook-zh.github.io/ 前言&#xff1a; GPT发展&#xff1a;GPT-1 2018 -->GPT-2&GPT-3&#xff08;扩大预训练数据和模型参数规模&#xff09;–> GPT-3.5&#xff08;代码训练、人类对齐、工具使用等&#xff09;–> 2022.11 ChatG…

海外云手机:出海电商养号智能化方案

随着出海电商的迅猛发展&#xff0c;使用海外云手机进行养号已经成为越来越多商家的新选择。尤其在社交电商推广和短视频引流方面&#xff0c;海外云手机不仅提高了流量的精准度&#xff0c;还助力商家实现业务的快速增长。本文将探讨海外云手机养号相较于传统模式的优势&#…

STM32CubeIDE(Eclipse)Post-build steps添加带参.exe实现全流程(1):带参.exe制作

0 工具准备 vscode&#xff0c;编辑C代码 Code Runner插件&#xff0c;用于生成exe 1 前言 使用STM32CubeIDE编译生成了二进制镜像文件后&#xff0c;有时为了防止镜像被恶意修改&#xff0c;可以通过添加校验和来对整个镜像进行保护&#xff0c;实现手段就是在STM32CubeIDE工…

精华分享 | 大模型LLM微调技巧与实践总结

导读 本文总结了作者在ChatGLM-6B模型微调的经验&#xff0c;并汇总了目前开源项目&数据。 写在前面 大型语言模型横行&#xff0c;之前非常焦虑&#xff0c;现在全面拥抱。目前也有很多开源项目进行大模型微调等&#xff0c;笔者也做了一阵子大模型了&#xff0c;特此来…

datawhale大模型bot应用开发--task4:图片流

一、图像流是专门用于图像处理的一个流程工具 在图像流中&#xff0c;你可以通过可视化的操作方式灵活添加各种用于图像处理的节点&#xff0c;构建一个图像处理流程来最终生成一个图像。图像流发布后&#xff0c;支持在 Bot 或工作流中使用。 二、图像流的能力范围 类型 图…

【Linux】进程--详细解释进程

目录 1、冯诺依曼体系结构 2、操作系统 3、进程 4、环境变量 5、进程地址空间 6、页表&#xff08;简单初步理解&#xff09; 1、冯诺依曼体系结构 a、存储器指的是&#xff1a;内存 外设&#xff1a; b、输入设备&#xff1a;鼠标&#xff0c;键盘&#xff0c;摄像头&am…

宠物用品在线交易:SpringBoot开发实战

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

Python入门(一)

心血来潮就干&#xff1a;python课程走起 和你一起学习 Python 语言的基础语法。你将会系统性地学习 Python 基础知识&#xff1b; 直接开始吧&#xff5e; 本篇文章将了解编程的几个基础概念。并且&#xff0c;你将学到如何在电脑屏幕上输出数字、文字&#xff0c;并敲出你…