上一章的BeanProcessor完成了类的实例化和注入操作。接下来则是 EventProcessor了。EventProcessor完成了对有所Listener和Subscriber事件的注册,以及触发了,监听在应用初始化完毕后的所有事件。
我们来看看代码
1 | public function handle(): bool |
由于BeanProcessor完成了注解类的实例化,这里就可以使用bean()函数来直接使用对象。
在这里我们可以清楚的看到,这个方法将所有事件对象,注册至监听事件中。然后触发生命周期为APP_INIT_COMPLETE的所有事件。
那么这个事件管理器的内部实现是怎样的呢?我们接下来就看一看。
Swoft的事件管理
在Swoft框架中,整个事件管理的核心是 EventManager。它一个分为两个模块,分别是Listener和Subscriber。这里我们讨论下Listener
我们在ListenerRegister::register()方法中看到,注册时是通过$em->addListener()的方法。
1 | public static function register(EventManager $em): array |
遍历静态变量$listeners,取出监听事件类名,然后获取其相应的以实例化好的对象,最后注入到$em->listeners数组中。
到这里可能有人有疑问了,这个self::$listeners的值是哪儿来的?其实这个值在上个AnnotationProcessor中已经完成。
我们知道,注解在初始化时,每个添加上注解的类都会根据其相应的parser做一些解析。观察下./vendor/swoft/event/src/parser目录就会知道。目录下的ListenerParser.php
1 | public function parse(int $type, $annotation): array |
在解析时,它将获取这个类的类名,然后调用注册进ListenerRegister::addListener()方法,将这些注入到ListenerRegister::$listeners中。所以在EventProcessor阶段中,才能遍历$listeners.
回到刚刚的问题$em->addListener()之后,在通过trigger()触发。Swoft在其生命周期的各个点,已经埋好了触发器。就比如在此时是swoft核心功能初始化完毕的时候,于是handle()最后就有Swoft::trigger(SwoftEvent::APP_INIT_COMPLETE),用于触发相关事件。
剩下的关于事件优先级触发的机制,这个部分在ListenerQueue.php的类中可以看到
1 | public function __construct() |
相同触发时间的事件,都会放在$this->queue中,而这个成员变量的本质其实是一个SplPriorityQueue(优先队列)。在这里不太了解数据结构,和PHPSPL相关知识的同学,可以去看一下。
总结
这里已经分析了Listener,其实Subscriber的实现方式跟其差不多,大家可以自己去看一下。下一个ConsoleProcessor可讲的不是太多。所以下一篇文章很有可能是对Swoft中的AOP概念的解析。