千家信息网

浅析easyswoole源码Di原理与实现

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,依赖注入简介:Dependency Injection 依赖注入EasySwoole实现了简单版的IOC,使用 IOC 容器可以很方便的存储/获取资源,实现解耦。使用依赖注入,最重要的一点好处就是有效
千家信息网最后更新 2026年10月31日浅析easyswoole源码Di原理与实现

依赖注入

  简介:Dependency Injection 依赖注入

  EasySwoole实现了简单版的IOC,使用 IOC 容器可以很方便的存储/获取资源,实现解耦。

  使用依赖注入,最重要的一点好处就是有效的分离了对象和它所需要的外部资源,使得它们松散耦合,有利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。

  在我们的日常开发中,创建对象的操作随处可见以至于对其十分熟悉的同时又感觉十分繁琐,每次需要对象都需要亲手将其new出来,甚至某些情况下由于坏编程习惯还会造成对象无法被回收,这是相当糟糕的。但更为严重的是,我们一直倡导的松耦合,少***原则,这种情况下变得一无是处。于是前辈们开始谋求改变这种编程陋习,考虑如何使用编码更加解耦合,由此而来的解决方案是面向接口的编程。

  --摘自《easyswoole开发文档》

本文将解析并实现下列功能。
  • 1、singleton模式的巧妙实现。
  • 2、通过Di方式实现简单的容器,方便存取资源,从而达到解耦的目的。
代码实现
文件结构

  • \client.php 功能调用入口
  • \AbstractInterface\Singleton.php 单例抽象接口
  • \Lib\Redis.php   redis服务类
  • \Service\Di.php   依赖注入实现简单Ioc容器
单例实现过程解读

client.php

 (string)$redisConfig['host'] ?? '',        'port' => (int)$redisConfig['port'] ?? '',        'timeout' => (string)$redisConfig['timeout'] ?? '',        'password' => (string)$redisConfig['password'] ?? '',        'database' => (int)$redisConfig['database'] ?? '',    ];    //直接访问    //Redis::getInstance($config)->set('hello', 'world');    //echo Redis::getInstance($config)->get('hello');    //Di::getInstance()->clear();    //注入容器    //--方法一、注入实例    //Di::getInstance()->set('redis', \App\Lib\Redis::getInstance($config));    //--方法二、容器内部实例化(支持单例模式)    Di::getInstance()->set('redis', \App\Lib\Redis::class, $config);    //通过容器获取实例    $redisInstance = Di::getInstance()->get('redis');    $redisInstance->set('dear', 'hui');    echo $redisInstance->get('hello') . PHP_EOL;    echo $redisInstance->get('dear') . PHP_EOL;} catch (\Exception $e) {    //throw $e;    echo $e->getMessage();}

\AbstractInterface\Singleton.php 单例抽象接口

namespace App\AbstractInterface;#声明为特性Trait Singleton{    private static $instance;    public static function getInstance(...$args)    {        if(!isset(self::$instance)){            //通过static静态绑定来new绑定的对象            self::$instance=new static(...$args);        }        return self::$instance;    }}

\Lib\Redis.php   redis服务类

namespace App\Lib;require_once APP_ROOT . '/AbstractInterface/Singleton.php';use App\AbstractInterface\Singleton;class Redis{        //这里通过使用特性来扩展Redis类的能力        //借助Singleton中的getInstance来new本类,创建redis连接实例        //Redis::getInstance(...)    use Singleton;    private $connectInstance = null;    /**     * Redis constructor.     * @param array $redisConfig     * @throws \Exception     */    private function __construct(array $redisConfig)    {        try {            //通过yaconf读取配置ini            if (!extension_loaded('redis')) throw new \Exception('Redis extension is not install');            $this->connectInstance = new \Redis();            $result = $this->connectInstance->connect($redisConfig['host'], $redisConfig['port'], $redisConfig['timeout']);            $this->connectInstance->auth($redisConfig['password']);            $this->connectInstance->select($redisConfig['database']);            if ($result === false) throw new \Exception('Connect redis server fail');        } catch (\Exception $e) {            throw $e;        }    }    public function __call($name, $arguments)    {        return $this->connectInstance->$name(...$arguments);    }}

Redis类引入Singleton特性,轻松实现单例子。

//通过Redis::getInstance就能获取实例
Redis::getInstance($config)->set('hello', 'world');
echo Redis::getInstance($config)->get('hello');

依赖注入的实现

\Service\Di.php   依赖注入实现简单Ioc容器

 container[$key] = [            'obj' => $obj,            'params' => $arg        ];    }    public function get(string $key)    {        if (!isset($this->container[$key])) return null;        $result = $this->container[$key];        if (is_object($result['obj'])) {            return $result['obj'];        } elseif (is_callable($result['obj'])) {// 检测参数是否为合法的可调用结构(function,class method)            return $result['obj'];        } elseif (is_string($result['obj']) && class_exists($result['obj'])) {            //通过反射方式获取实例化对象            $reflection = new \ReflectionClass($result['obj']);            $constructor = $reflection->getConstructor();                        $instance = null;            if ($constructor->isPublic()) {//直接实例化                $instance = $reflection->newInstanceArgs($result['params']);            } elseif ($constructor->isPrivate()) {//支持单例模式                if ($reflection->hasMethod('getInstance')) {                    $instance = $result['obj']::getInstance($result['params']);                }            }             $this->container[$key]['obj'] = $instance;            return $instance;        } else {            return $result['obj'];        }    }    public function clear(): void    {        $this->container = [];    }    public function delete($key): void    {        unset($this->container[$key]);    }}

在client.php中使用Di的使用

//向容器中注入实例
//Di::getInstance()->set('redis', \App\Lib\Redis::getInstance($config));
Di::getInstance()->set('redis', \App\Lib\Redis::class, $config);

//通过容器获取实例
$redisInstance = Di::getInstance()->get('redis');

$redisInstance->set('dear', 'hui');
echo $redisInstance->get('hello') . PHP_EOL;
echo $redisInstance->get('dear') . PHP_EOL;

总结

本案例涉及知识点:
1.通过Yaconf扩展高效获取配置信息
2.static静态绑定、trait特性
3.singleton模式的实现
4.Di依赖注入

附:Yaconf配置文件(easyswoole_api.ini)格式

redis.host = '192.168.1.99'
redis.port = 6379
redis.password = 'helloworld'
redis.database = 12
redis.timeout = 3

实例 容器 对象 模式 特性 功能 接口 结构 解耦 资源 编程 配置 重要 情况 文件 方式 方法 静态 开发 支持 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 今日互联网科技 互联网未来科技 浩特互联网科技 科技互联网公司logo 伴你行互联网科技有限公司 互联网科技有限公司 翻译 天速互联网络科技有限公司 温州喔噻互联网科技有限公司 崇明区互联网教育科技售后服务 苏州铭阳互联网科技有限公司 成都互联网科技公司工作好不好 亳州好赞互联网科技有限公司 天津腾达互联网科技有限公司 互联网科技如何创业 广东工业互联网大赛深圳学泰科技 富国互联网金融科技混合基金 工业互联网科技成果转化 广州三三互联网科技有限公司 杭州科技互联网公司有哪些 六子台科技互联网展会 手冲咖啡和咖啡机区别 互联网科技公司发展 世界互联网领先科技成果 华中科技大学互联网 郑州华宇互联网科技 互联网金融监管科技 互联网校园科技培训 互联网金融中的现代科技 互联网科技与大数据专业 中国互联网公司排名锤子科技
0