事件系统与服务容器

理论突破,往往带来实践的创新。反之实践不甚其解,通常是没有掌握好理论。Symfony事件系统,涉及到派遣器(事件触发),订阅器(事件收集),事件对象(数据附加),监听器(事件执行),事件传播,事件队列优先级,以及程序组件间的通信

服务容器

每一个服务都被存放于一个特殊的名为 service container(服务容器)之中 容器把对象的组织方式中心化

  • 取得并使用服务
    • 在控制器中借助“服务的类名或接口名”, 对 action 的参数进行 type-hinting 以“请求”容器中的服务
    • 可以使用唯一的 "Service ID" 来直接访问服务, 继承 Controller 类时内部可直接从容器中取出服务

事件派遣

Symfony 自身提供的内部事件,被定义在 KernelEvents 类中 在 sf 程序执行期间,大量的事件通知会被触发,程序可监听这些通知,并执行任意代码作为响应

  • 事件监听器
    • 通常由事件类和监听接口组成
    • 接收事件对象参数,事件对象持有派遣器自身引用,该引用实例可决定事件能否继续传播
    • 事件监听器优先级,Symfony的内部监听,其优先级范围是-255到255,默认值为0,顺序执行
  • 监听器模式
    • 监听者模式是基于:注册-回调的事件/消息通知处理模式,就是被监控者将消息通知给所有监控者
  • 事件派遣器
    • 事件触发调用者,事件源
    • 事件类注册成服务,可命名 tags
    • 一个单一的事件派遣器创建之后,它要维护全部相关监听器的“登记”
    • 当事件通过 dispatcher 被派遣时,所有已注册的监听器会接到通知
    • 内核通知 dispatcher 对象派遣事件,派遣器通知事件的全部监听器,监听器执行
  • 事件订阅
    • 订阅器始终明确知道正在监听的事件
    • 定义了一个或多个方法,用于监听一个或多个事件
  • 监听 VS 订阅
    • 订阅器易于复用 与事件有关的内容存在于类中,而不是存在于服务定义中,故 sf 内部使用订阅器
    • 监听器更灵活,因 bundles 可以有条件地开启或关闭它们,基于配置文件中的某些“选项值”

EventDispatcher组件

  • 作用 使组件之间“通过派遣事件和监听事件”进行互相通信
  • 应用背景
    • 需要在项目中提供一个插件系统
    • EventDispatcher 组件以一种简单高效的方式,实现了 Mediator 设计模式
      • 中介者定义一个接口用于与各同事对象通信
      • 每一个同事对象在需与其他同事通信时,与它的中介者通信
      • 使控制集中化,减少了子类的生成,将各个同事类解耦,协议多向
      • 可以使用 Observer 模式与 Mediator 通信
    • 事件
      • 当一个事件被派遣时,该事件被多个监听器来监听。
      • 一个Event实例将被同时创建,并被传递给所有的监听器
      • Event 对象自身往往包含着被派遣事件的数据
    • 事件名称和事件对象
      • Event 类 默认包含一个用于停止 event.propagation方法
      • 特定事件的数据,则为一个拥有附加方法来取得或重写这些数据的特殊子类
    • 连接到监听器
      • 欲利用已有的事件,需要访问派遣器下的监听器
      • 派遣器的addListener()方法被调用时,可以把任何一个有效的PHP回调(callable)关联到那个事件
        • 同 yii2 一样, 监听器addListener()方法有三个参数
        • 事件名称(字符串),监听器需要监听到它
        • 一个PHP回调,将在特定的事件被派遣时被执行
        • 一个可选的整数优先级(愈高则愈重要,该监听将被愈早地触发)
      • 一旦监听被注册到派遣器,它就等待着事件被通知(到自己)
      • 在服务容器中注册事件监听
        • 支持把事件派遣器注册成服务
        • 支持把监听器注册成服务
        • 支持把订阅器注册成服务
    • 派遣Event
      • dispatch() 方法可以通知给定事件的全部监听
        • 要派遣的事件名称,以及用于传给每个监听的Event实例
      • 事件派遣器永远返回被派遣的事件对象
    • 使用事件订阅器
      • 监听事件的常规方式就是去注册一个监听器给事件派遣器
      • 或通过event subscriber(订阅器), 向派遣器精确通报它要订阅哪些事件
        • 除了它自己告诉派遣器“要监听哪些事件”之外,也需要将该订阅器注册给派遣器
    • 停止Event Flow/Propagation
      • 原因 在某些场合,一个监听在作动时,防止其他监听被调用是有意义
        • 换言之,监听器必须能够告诉派遣器,停止向后续的监听进行关于此事件的全部传播
      • EventDispatcher Aware 的事件和监听
        • EventDispatcher 始终向监听器传递被派遣的事件、事件名和一个对派遣器自身的引用
  • 其他派遣器
    • The Container Aware Event Dispatcher
    • The Immutable Event Dispatcher
    • The Traceable Event Dispatcher(由HttpKernel组件提供)
本作品采用《CC 协议》,转载必须注明作者和本文链接
pardon110
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
开发者 @ 社科大
文章
134
粉丝
24
喜欢
101
收藏
55
排名:106
访问:8.9 万
私信
所有博文
社区赞助商