首页 > 其他分享 >hyperf3 框架原理

hyperf3 框架原理

时间:2023-04-17 21:55:23浏览次数:32  
标签:function __ 框架 hyperf3 loader method Inject 原理 class

一: hyperf 核心组件

1681737081399.jpg

二: Inject 实现原理

1: 通过InjectAspect代理了Inject注解
2: 具体执行逻辑扫,框架加载开始描所有的类,只要包含Inject注解的都会生成一个proxy类
3: ClassLoader 拦截Composer原始加载类方法,定位到proxy 文件类,通过__handlePropertyHandler 注入Inject注解的属性

代码块一
// Proxy the composer class loader
        foreach ($loaders as &$loader) {
            $unregisterLoader = $loader;
            if (is_array($loader) && $loader[0] instanceof ComposerClassLoader) {
                /** @var ComposerClassLoader $composerClassLoader */
                $composerClassLoader = $loader[0];
                AnnotationRegistry::registerLoader(function ($class) use ($composerClassLoader) {
                    return (bool) $composerClassLoader->findFile($class);
                });
                $loader[0] = new static($composerClassLoader, $proxyFileDirPath, $configDir, $handler);
            }
            spl_autoload_unregister($unregisterLoader);
        }

代码块二
 foreach ($classes as $className => $reflectionClass) {
            $reflectionClassMap[$className] = $reflectionClass->getFileName();
            if ($this->filesystem->lastModified($reflectionClass->getFileName()) >= $lastCacheModified) {
                /** @var MetadataCollector $collector */
                foreach ($collectors as $collector) {
                    $collector::clear($className);
                }

                $this->collect($annotationReader, $reflectionClass);
            }
        }
        $this->loadAspects($lastCacheModified);
      .....
      .....
    // Get the class map of Composer loader
        $classMap = array_merge($reflectionClassMap, $classMap);
        $proxyManager = new ProxyManager($classMap, $proxyDir);
        $proxies = $proxyManager->getProxies();



以IndexController为例
class IndexController extends AbstractController
{
    use \Hyperf\Di\Aop\ProxyTrait;
    use \Hyperf\Di\Aop\PropertyHandlerTrait;
    function __construct()
    {
        if (method_exists(parent::class, '__construct')) {
            parent::__construct(...func_get_args());
        }
        $this->__handlePropertyHandler(__CLASS__);
    }
    /**
     * @Inject()
     * @var BaseService
     */
    public $someService1;
    /**
     * @return array
     */
    public function index()
    {
        $this->someService1->index();
        $user = $this->request->input('user', 'Hyperf');
        $method = $this->request->getMethod();
        //var_dump($this);
        return ['method' => $method, 'message' => "Hello {$user}."];
    }
}

__handlePropertyHandler 就是属性注入逻辑

三: IOC注入分为哪些方式

1: Inject注入
2: 函数或是构造参数注入,无需使用Inject注解

四: Aspect切面实现

1: 通过上述的loadAspects方法生成代理类,在runtime/container/proxy 文件夹下面
2: 执行时通过 self::__proxyCall 拦截运行方法,执行切面的process方法
3: InjectAspect比较特殊,不需要执行切面的process 处理逻辑

4: 案例代码块如下

class SomeService extends BaseService
{
    use \Hyperf\Di\Aop\ProxyTrait;
    use \Hyperf\Di\Aop\PropertyHandlerTrait;
    function __construct()
    {
        if (method_exists(parent::class, '__construct')) {
            parent::__construct(...func_get_args());
        }
        $this->__handlePropertyHandler(__CLASS__);
    }
    public function index()
    {
        $__function__ = __FUNCTION__;
        $__method__ = __METHOD__;
        return self::__proxyCall(__CLASS__, __FUNCTION__, self::__getParamsMap(__CLASS__, __FUNCTION__, func_get_args()), function () use($__function__, $__method__) {
        });
    }
}

五:Amqp 的@Consumer 和 apolle启动拉配置实现方式

1: 通过ConfigProvider listeners 参数注入配置,框架启动时会在预设点dispatcher 对应的event 事件注入的观察者
2: 常见的event有
image.png
3: apolle 同理如上
4: 所以实现自定义的插件需要提供ConfigProvider配置文件

六:框架中比较重要的两个命令

1: vendor:publish 用来发布配置文件,tp,laravel都有
2: package:discover 用来注入ServiceProvder,ioc中重要的一环,tp,laravel都有,hyperf 暂时未使用

标签:function,__,框架,hyperf3,loader,method,Inject,原理,class
From: https://www.cnblogs.com/bigmiao/p/17327654.html

相关文章

  • 理解Android系统的进程间通信原理(一)----RPC中的代理模式
    理解Android系统的进程间通信原理(一)----RPC中的代理模式Android系统中的进程间通信是通过一个轻量级的RPC(RemoteProcedureCall远程进程调用)和AIDL(AndroidInterfaceDefininationLanguage)规范来生成两个进程之间可以相互访问的代码。其中RPC是以接口方式来实现,客户端与被......
  • python爬虫scrapy框架的使用
    总结scrapystartprojectnamescrapygenspiderbaiduhttp://www.baidu.comscrapycrawlbaiduscrapy项目创建scrapystartprojectscrapy_baidu_091创建爬虫文件在spider中创建爬虫文件#scrapygenspider名称域名(不写http)scrapygenspiderbaiduhttp://www.b......
  • TAB命令补全及补全路径原理
    tab建可以实现命令及路径等补全,提高输入效率,避免出错命令补全:外部命令:bash根据PATH环境变量定义的路径,自左而右在每个路径搜寻以给定命令名命名的文件,第一次找到的命令即为要执行的命令。命令的子命令补全,需要安装bash-completion路径补全:把用户给出的字符串当做路径开头,并在其......
  • Java集合框架
    Java集合框架概述Java集合框架是一个抽象数据类型的框架,它提供了一组接口和类,可用于处理各种类型的数据结构,如列表、队列、集、映射等。Java集合框架的主要特点是:1、可扩展性:Java集合框架提供了一组可扩展的接口和类,可让开发人员根据自己的需要实现新的数据结构和算法。2、高性能:Ja......
  • FinClip 与 uniapp:轻应用平台与前端开发框架
    原文地址juejin.cnFinClip背后的产品经理发现很多开发者或业务部门的朋友,在刚了解到FinClip的时候,都会好奇FinClip能解决怎样的问题,也会经常将FinClip与uni-app进行对比考虑二者的区别与优劣势。因此在本文中,FinClip的产品经理会和我们深入地探讨FinClip与uni-app之......
  • k8s 工作原理以及常用基础
    k8s是什么☛可移植:支持公有云,私有云,混合云,多重云☛可扩展:模块化,插件化,可挂载,可组合☛自动化:自动部署,自动重启,自动复制,自动伸缩/扩展k8s核实组件1)主要组件●etcd:保存了整个集群的状态;●apiserver:提供了资源操作的唯一入口,并提供访问控制、API注册和发现等机制......
  • 国内开源js框架
    JX(腾讯)–http://alloyteam.github.com/JXKISSY(淘宝)–http://www.kissyui.comQWrap(百度)-Tangram(百度)–http://tangram.baidu.comComo–http://www.comsome.comEdoJs–KindEditor–https://github.com/kindsoft/kindeditorNJF–http://code.google.com/p/njf......
  • Vue - watcher原理
    原理Watcher原理是先把自己设置到全局唯一指定的位置(window.target),然后读取数据。因为读取了数据,所以会触发这个数据的getter。然后在getter中就会从全局唯一的那个位置读取真正读取数据的watcher,并把这个watcher收集到Dep中去。通过这样的方式,watcher可以主动去订阅任意一个数......
  • flask请求上下文分析(request原理)、wtforms
    上节回顾#1蓝图第一步:导入第二步:实例化得到对象,可以指定static和templates第三步:app中注册蓝图,注册蓝图时,可以指定前缀第四步:使用蓝图,注册路由,注册请求扩展#2g对象当次请求的全局对象,在当次请求中可以放值和取值跟session的区别是session可......
  • 通过一个具体的例子,深入了解 SAP UI5 控件数据双向绑定的工作原理和问题排查方法试读
    笔者知识星球里有朋友提问:SAPUI5中的sap.m.select控件,在当前页面做任何操作时,都可以选中key值,但触发dialog之后,可以看到select框内的key值被清空,当关闭dialog后,再去选择key值,无任何反应,请问是select控件的问题还是dialog的问题又或者是odata写法有问题,谢谢!......