对 hyperf 的 container 和 AOP 的理解

2 篇文章 0 订阅

Container

基本思路和 这篇文章:《Laravel 服务容器实例教程 —— 深入理解控制反转(IoC)和依赖注入(DI) 》 是一致的, 再结合 hyperf 文档: https://hyperf.wiki/2.0/#/zh-cn/di 理解即可。

首先依赖注入就是为了降低耦合, 所以比如你需要一个 UserService , 本来定义了类 UserService , 那么直接调用就好了。 但是万一哪天想用的是 UserPlanBService
于是你要改所有 new UserService的地方, 很麻烦,也就是紧耦合了
即使你通过类的构造函数 或者 注解 @inject 的地方,但是也要去比较多的地方修改,而且还不一定是哪个文件引用了

先说结论是: hyperf 做到了你只需要修改 config/autoload/dependencies.php 这个文件就能实现调用不同的 UserService。

<?php
return [
\App\Service\UserServiceInterface::class => \App\Service\UserService::class];

再次细说:
你希望能够把 UserService 解耦, 但是业务上比如需要 UserService 的 getInfoById() 这个接口,那么无论你怎么更换 UserPlanNService ,都必须实现这个接口,否则程序就运行不下去了。
因此定义一个 Interface 就呼之欲出了。 那么以后你只要注入 这个 interface , 而且 dependence 指定了具体实现在哪 ,所以也就做到了 解耦。

继续深入,上述虽然解耦了 但是不够灵活,不能处理更复杂的情况,比如 UserService 在实例化的时候需要判断配置文件是否开启了缓存(构造函数初始化可以更加的灵活)那么实现思路自然是工厂类,即在 UserService 上再加一层
代码示例:

<?php
namespace App\Service;

use Hyperf\Contract\ConfigInterface;use Psr\Container\ContainerInterface;

class UserServiceFactory{
// 实现一个 __invoke() 方法来完成对象的生产,方法参数会自动注入一个当前的容器实例
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
namespace App\Service;

class UserService implements UserServiceInterface{

/**
* @var bool
*/
private $enableCache;

public function __construct(bool $enableCache)
{
// 接收值并储存于类属性中
$this->enableCache = $enableCache;
}

public function getInfoById(int $id)
{
return (new Info())->fill($id);
}}

那么绑定关系就是绑定工厂类了

<?php
return [
\App\Service\UserServiceInterface::class => \App\Service\UserServiceFactory::class];

上述这些也就是 hyperf 的 container 做的事情,如果你直接调用 new UserService 肯定是不行的。

AOP - 面向切面编程

用通俗的话来讲,就是在 Hyperf 里可以通过 切面(Aspect) 介入到任意类的任意方法的执行流程中去,从而改变或加强原方法的功能,这就是 AOP。

大致可以参考 hyperf/cache 提供的使用 AOP 的方法 , 代码:vendor/hyperf/cache/src/Aspect/CacheableAspect.php
大致应该就是 缓存切入注解

public $annotations = [
    Cacheable::class,
];

发现有 Cacheable::class 这个注解的,(也就是 @Cacheable()) 则切入

// 获取类相关信息
$className = $proceedingJoinPoint->className;
$method = $proceedingJoinPoint->methodName;
$arguments = $proceedingJoinPoint->arguments['keys'];

// 获取 缓存的 key , ttl 等
[$key, $ttl, $group, $annotation] = $this->annotationManager->getCacheableValue($className, $method, $arguments);
// 获取使用的 缓存驱动
$driver = $this->manager->getDriver($group);
// 查找缓存,命中直接返回,未命中则继续执行原有函数
[$has, $result] = $driver->fetch($key);
if ($has) {
    return $result;
}
// 执行原有函数
$result = $proceedingJoinPoint->process();
// 根据之前获取的 key ttl 等设置缓存 
$driver->set($key, $result, $ttl);
if ($driver instanceof KeyCollectorInterface && $annotation instanceof Cacheable && $annotation->collect) {
    $driver->addKey($annotation->prefix . 'MEMBERS', $key);
}

return $result;
  • 0
    点赞
  • 5
    收藏
  • 打赏
    打赏
  • 0
    评论
Hyperf 是基于 Swoole 4.5+ 实现的高性能、高灵活性的 PHP 协程框架,内置协程服务器及大量常用的组件,性能较传统基于 PHP-FPM 的框架有质的提升,提供超高性能的同时,也保持着极其灵活的可扩展性,标准组件均基于 PSR 标准 实现,基于强大的依赖注入设计,保证了绝大部分组件或类都是可替换 与可复用的。 框架组件库除了常见的协程版的 MySQL 客户端、Redis 客户端,还为您准备了协程版的 Eloquent ORM、WebSocket 服务端及客户端、JSON RPC 服务端及客户端、GRPC 服务端及客户端、Zipkin/Jaeger (OpenTracing) 客户端、Guzzle HTTP 客户端、Elasticsearch 客户端、Consul 客户端、ETCD 客户端、AMQP 组件、NSQ 组件、Nats 组件、Apollo 配置中心、阿里云 ACM 应用配置管理、ETCD 配置中心、基于令牌桶算法的限流器、通用连接池、熔断器、Swagger 文档生成、Swoole Tracker、视图引擎、Snowflake 全局 ID 生成器 等组件,省去了自己实现对应协程版本的麻烦。 Hyperf 还提供了基于 PSR-11 的依赖注入容器、注解、AOP 面向切面编程、基于 PSR-15 的中间件、自定义进程、基于 PSR-14 的事件管理器、Redis/RabbitMQ/NSQ/Nats 消息队列、自动模型缓存、基于 PSR-16 的缓存、Crontab 秒级定时任务、Translation 国际化、Validation 验证器等非常便捷的功能,满足丰富的技术场景和业务场景,开箱即用。 框架初衷: 尽管现在基于 PHP 语言开发的框架处于一个百家争鸣的时代,但仍旧未能看到一个优雅的设计与超高性能的共存的完美框架,亦没有看到一个真正为 PHP 微服务铺路的框架,此为 Hyperf 及其团队成员的初衷,我们将持续投入并为此付出努力,也欢迎你加入我们参与开源建设。 设计理念: Hyperspeed + Flexibility = Hyperf,从名字上我们就将超高速和灵活性作为 Hyperf 的基因。 对于超高速,我们基于 Swoole 协程并在框架设计上进行大量的优化以确保超高性能的输出。 对于灵活性,我们基于 Hyperf 强大的依赖注入组件,组件均基于 PSR 标准的契约和由 Hyperf 定义的契约实现,达到框架内的绝大部分的组件或类都是可替换的。 基于以上的特点,Hyperf 将存在丰富的可能性,如实现 Web 服务,网关服务,分布式中间件,微服务架构,游戏服务器,物联网(IOT)等。 运行环境: Linux, OS X or Cygwin, WSL PHP 7.2+ Swoole 4.4+

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论

打赏作者

Simael__Aex

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值