Magento 2 Plugin - Interceptor - Magento 2插件 - 拦截器

Magento 2 Plugin is a technical plugin for your better writing code. Interception Plugin is referred to a little magento 2 extension that allows editing the behavior of any public class or method by intercepting a function call and running code either before or after or around the function call. By using this Magento 2 Plugin Interception, you can modify the behavior of a class while there is no need to change the class directly.

Magento 2插件是一个技术插件,可以更好地编写代码。拦截插件被称为一个小的magento 2扩展,它允许通过在函数调用之前或之后拦截函数调用和运行代码来编辑任何公共类或方法的行为。通过使用此Magento 2插件拦截,您可以修改类的行为,而无需直接更改类。

Maybe you still think the observers can help you do that fluently but some differences need to be pointed out. Particularly, not only create functions of a class using dependency injection but Interception plugin can also be confirmed with a sortOrder, that allows checking the chain and order on which plugins run. That is the reason why this plugin doesn’t make the class change and doesn’t have any conflict with one another

也许你仍然认为观察者可以帮助你流利地做到这一点,但需要指出一些差异。特别是,不仅使用依赖注入创建类的函数,而且还可以使用sortOrder确认Interception插件,该sortOrder允许检查链接和运行插件的顺序。这就是为什么这个插件不会使类更改并且彼此之间没有任何冲突的原因

1.Magento 2插件的好处

对于像您一样的模块开发人员,Magento 2 Interception插件允许:

  • 转发在对象管理器控制的对象上使用的任何方法调用并采取编程操作
  • 修改在对象管理器控制的对象上使用的任何方法调用的返回值
  • 修改在对象管理器控制的对象上使用的任何方法调用的参数
  • 当其他模块以相同或可预测的方式进行相同方法时,类似地继续进行。

如果您从未有过以这种方式创建系统的经验,那么当您对性能特征感到困惑时,并不奇怪。
但与Mageplaza开发团队合作,他们对专业知识充满信心,知道应该为这项工作应用哪些软件设计模式。
在本主题中,可能会给出很少的拦截器模式,因此如果您需要获取更多信息或本帖子范围内未包含的任何问题,请在此处与我们联系

2.Magento 2插件的限制

什么情况Magento 2 Interception插件无法使用?

  1. 在Magento \ Framework \ Interception之前实例化的对象是自我引导运行的;
  2. 最后的方法;
  3. 最后的类;
  4. 任何包含至少一个最终公共方法的类;
  5. 非 Public 方法(Non-public methods);
  6. 类方法(如静态方法);
  7. __construct;
  8. 虚拟类型(Virtual types);

3.创建Magento 2新插件的指南

  1. 在Magento 2中声明一个插件:

    <config>
    <type name="{ObservedType}">
    <plugin name="{pluginName}" type="{PluginClassName}" sortOrder="1" disabled="false"/>
    </type>
    </config>

      解释:
    1.必需的选项:

    type name:输入需要遵循的类或接口的名称。
    plugin name:标识插件的任意插件名称。还用于合并插件的配置。
    plugin type:填写插件类的名称或其虚拟类型。您可以为此字段引用以下命名约定:\Vendor\Module\Plugin\<ModelName>Plugin。

    2.可选选项:

    plugin sortOrder:当插件调用进程中的其他相同方法时设置顺序。
    plugin disabled:这允许您快速启用或禁用插件。作为默认配置,所选值为false。使用此属性可禁用di.xml文件中的核心或第三方插件。

    3.如下例所示,我们将编辑 app\code\Mageplaza\HelloWorld\etc\di.xml, 您需要插入代码段:

    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
    <type name="Mageplaza\HelloWorld\Controller\Index\Example">
    <plugin name="Mageplaza_HelloWorld_Plugin" type="Mageplaza\HelloWorld\Plugin\ExamplePlugin" sortOrder="10" disabled="false" />
    </type>
    </config>

      例如,下面的代码定义了类型名称,我们在 app/code/Mageplaza/HelloWorld/Controller/Index/  /创建了Example.php文件

    内容如下:

    <?php
    
    namespace Mageplaza\HelloWorld\Controller\Index;
    
    class Example extends \Magento\Framework\App\Action\Action
    { protected $title; public function execute()
    {
    echo $this->setTitle('Welcome');
    echo $this->getTitle();
    } public function setTitle($title)
    {
    return $this->title = $title;
    } public function getTitle()
    {
    return $this->title;
    }
    }

      使用插件名称,我们在 app/code/Mageplaza/HelloWorld/Plugin/ /创建了Example.php文件:

    内容如下:

    <?php
    
    namespace Mageplaza\HelloWorld\Plugin;
    
    class ExamplePlugin{
    
    }
    
  2. 在Magento 2中定义一个插件

    插件是通过在方法之前,之后或周围使用代码来扩展或编辑公共方法行为的好方法。
    首先,请获取一个对象,该对象提供对被观察方法类的所有公共方法的许可。

    插件中的3种方法

    1. before - beforeDispatch()
    2. around - aroundDispatch()
    3. after - afterDispatch()

    1. Before methods:在方法是在观察方法中运行的第一种方法之前,这些方法必须与前面标签 before 的观察名称具有相同的名称。

    要应用before方法来修改观察方法的参数的话,可以返回修改后的参数。如果有多个参数,则返回将根据这些参数的范围执行。如果返回无效,则意味着不应修改被观察方法的参数。如下:

    <?php
    
    namespace Mageplaza\HelloWorld\Plugin;
    
    class ExamplePlugin
    { public function beforeSetTitle(\Mageplaza\HelloWorld\Controller\Index\Example $subject, $title)
    {
    $title = $title . " to ";
    echo __METHOD__ . "</br>"; return [$title];
    } }

      

    2.After methods:方法在观察到的方法完成后立即开始运行,并且这些方法必须与观察到的名称具有相同的名称,而前缀标签是“after”。

    在方法之后,负责以正确的方式编辑观察方法的结果并且需要具有返回值。如下:

    <?php
    
    namespace Mageplaza\HelloWorld\Plugin;
    
    class ExamplePlugin
    { public function afterGetTitle(\Mageplaza\HelloWorld\Controller\Index\Example $subject, $result)
    { echo __METHOD__ . "</br>"; return '<h1>'. $result . 'Mageplaza.com' .'</h1>'; } }

      

    3. Around methods(围绕方法):around方法允许代码在observe方法之前和之后运行,因此您可以覆盖方法。这些方法必须与观察到的名称具有相同的名称,而前缀标签为“around”。

    在排列原始方法的参数之前,可以将来自around方法的可调用 callable 到链中的下一个方法,这意味着还会调用下一个插件或观察到的函数。
    注意:如果未声明 callable,则不会调用下一个插件和原始方法。

    <?php
    
    namespace Mageplaza\HelloWorld\Plugin;
    
    class ExamplePlugin
    { public function aroundGetTitle(\Mageplaza\HelloWorld\Controller\Index\Example $subject, callable $proceed)
    { echo __METHOD__ . " - Before proceed() </br>";
    $result = $proceed();
    echo __METHOD__ . " - After proceed() </br>"; return $result;
    } }

      
    4. Check the result (检查结果):ExamplePlugin.php的所有内容如下:

    <?php
    
    namespace Mageplaza\HelloWorld\Plugin;
    
    class ExamplePlugin
    { public function beforeSetTitle(\Mageplaza\HelloWorld\Controller\Index\Example $subject, $title)
    {
    $title = $title . " to ";
    echo __METHOD__ . "</br>"; return [$title];
    } public function afterGetTitle(\Mageplaza\HelloWorld\Controller\Index\Example $subject, $result)
    { echo __METHOD__ . "</br>"; return '<h1>'. $result . 'Mageplaza.com' .'</h1>'; } public function aroundGetTitle(\Mageplaza\HelloWorld\Controller\Index\Example $subject, callable $proceed)
    { echo __METHOD__ . " - Before proceed() </br>";
    $result = $proceed();
    echo __METHOD__ . " - After proceed() </br>"; return $result;
    } }

      在此之后,请刷新缓存并检查结果。它会像这样显示出来

    如果您的插件是通过与参数匹配的方法调用的,它也必须与它们匹配,同时,您需要仔细遵循它们。在此过程中,请注意方法的原始签名以及默认参数和建议类型。

    例如,应用以下代码来标识可以为 nullable:的 SomeType  类型的参数:

    <?php
    namespace Mageplaza\HelloWorld\Model; class MyUtility
    {
    public function save(SomeType $obj = null)
    {
    //do something
    }
    }

      
    如果你用下面的插件包装这个方法:

    <?php
    namespace Mageplaza\HelloWorld\Plugin; class MyUtilityPlugin
    {
    public function aroundSave(\Mageplaza\HelloWorld\Model\MyUtility $subject, \callable $proceed, SomeType $obj)
    {
    //do something
    }
    }

      注意: Missing = Null

    如果您将该方法与null一起调用,则PHP会产生致命错误(fatal error),因为您的插件中不允许使用插件null。
    此外,遵循方法调用的插件中的参数非常重要。
    但如果不关心参数,请使用 use the variadics and argument unpacking 来完成此操作:

    <?php
    namespace Mageplaza\HelloWorld\Plugin; class MyUtilityPlugin
    {
    public function aroundSave(\Mageplaza\HelloWorld\Model\MyUtility $subject, \callable $proceed, ...$args)
    {
    //do something
    $proceed(...$args);
    }
    }

      

  3. Set priority for plugins (设置插件的优先级):

    sortOrder 选项允许 将正在观察相同方法的插件放入队列中。
    当方法开始调用之前,之后或周围时,插件将逐个应用。

4. 插件实例:Visit-访问 https://github.com/mageplaza/magento2-samples/tree/master/sample-module-interception

作者翻译:徐锅
转发请注明来源。
翻译来源:https://www.mageplaza.com/magento-2-module-development/magento-2-plugin-interceptor.html

Magento 2 Plugin - Interceptor - Magento 2插件 - 拦截器-插件开发的更多相关文章

  1. Mybatis拦截器执行过程解析

    上一篇文章 Mybatis拦截器之数据加密解密 介绍了 Mybatis 拦截器的简单使用,这篇文章将透彻的分析 Mybatis 是怎样发现拦截器以及调用拦截器的 intercept 方法的 小伙伴先按 ...

  2. Mybatis那些事-拦截器(Plugin+Interceptor)

    作者:yhjyumi的专栏 数据权限实现(Mybatis拦截器+JSqlParser) Mybatis的拦截器实现机制,使用的是JDK的InvocationHandler. 当我们调用Paramete ...

  3. mybatis Interceptor拦截器代码详解

    mybatis官方定义:MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis ...

  4. 过滤器(Filter)与拦截器(Interceptor )区别

    目录 过滤器(Filter) 拦截器(Interceptor) 拦截器(Interceptor)和过滤器(Filter)的区别 拦截器(Interceptor)和过滤器(Filter)的执行顺序 拦截 ...

  5. Flume 拦截器(interceptor)详解

    flume 拦截器(interceptor)1.flume拦截器介绍拦截器是简单的插件式组件,设置在source和channel之间.source接收到的事件event,在写入channel之前,拦截 ...

  6. CXF之五 拦截器Interceptor

    拦截器(Interceptor)是CXF功能最主要的扩展点,可以在不对核心模块进行修改的情况下,动态添加很多功能.拦截器和JAX-WS Handler.Filter的功能类似,当服务被调用时,就会创建 ...

  7. Hibernate拦截器(Interceptor)与事件监听器(Listener)

    拦截器(Intercept):与Struts2的拦截器机制基本一样,都是一个操作穿过一层层拦截器,每穿过一个拦截器就会触发相应拦截器的事件做预处理或善后处理. 监听器(Listener):其实功能与拦 ...

  8. MVC框架的插件与拦截器基础

    自制MVC框架的插件与拦截器基础 上篇谈到我自己写的MVC框架,接下来讲讲插件及拦截器! 在处理一些通用的逻辑最好把它封装一个插件或者拦截器,以便日后可以直接拿过来直接使用.在我的框架中可以通过继承以 ...

  9. CXF实战之拦截器Interceptor(四)

    拦截器(Interceptor)是CXF功能最基本的扩展点,能够在不正确核心模块进行改动的情况下.动态加入非常多功能.拦截器和JAX-WS Handler.Filter的功能相似,当服务被调用时.就会 ...

随机推荐

  1. Apex 中 PageReference 的使用

    PageReference类的作用 PageReference类位于Apex的System命名空间下.它可以用来在Apex代码中将页面跳转到指定的位置.在开发的时候,我们也可以向其中添加任意的参数. ...

  2. 解决Android Studio编译后安装apk报错:Error while Installing APK

    刚开始玩 Android ,用Android studio  连接真机做测试,在虚拟机上没有问题,但是真机就会报错 检查了好多地方,最终发现了问题,网上的常规就不介绍了,大家自己去看别的帖子 手机方面 ...

  3. mac /linux vi/vim永久显示行号开启高亮模式

    临时显示:进入vi编辑器,输入命令 :set number     //下次在进入vi 无法显示行号 :set nonumber  //本次vi关闭行号显示 vi 每次修改后推荐使用命令: sourc ...

  4. 07-Vue的基础使用

    vue的介绍 前端框架和库的区别 nodejs的简单使用 vue的起步 指令系统 组件的使用 过滤器的使用 watch和computed 钩子函数 渐进式的JavaScript框架 vue react ...

  5. tofixed方法 四舍五入

    tofixed方法 四舍五入 toFixed() 方法可把 Number 四舍五入为指定小数位数的数字.例如将数据Num保留2位小数,则表示为:toFixed(Num):但是其四舍五入的规则与数学中的 ...

  6. Linux学习历程——Centos 7 top命令

    一.命令介绍 top 命令用于动态的监控进程活动与系统负载信息. 格式为 top [参数] 二.实例 直接运行top命令 top命令执行结果的前五行为系统整体的统计信息,代表含义如下: 第1行:系统时 ...

  7. MFC映射

    所有CDC输出函数最终都会输出到物理平面(屏幕窗口.打印纸等).这些物理平面的单位量化往往多种多样,比如像素.打印点.英寸.毫米等等.这样可能会造成很多混乱,所以CDC输出对所有物理平面进行统一抽象化 ...

  8. 如何使用U盘安装macOS high Sierra?

    当你不再只是想升级系统的时候,而是想把系统重装,你可能就会用到如标题所说的方式:使用U盘安装mac系统.所以我们需要做以下几件事情,就可以顺利地重装mac系统: 第一步.在App Store下载最新的 ...

  9. 【English】20190418

    interested 感兴趣的[ˈɪntrəstɪd] arrange your time 安排自己时间[əˈreɪndʒ] If interested, please arrange your ti ...

  10. C#基础知识之字符串比较方法:“==”操作符;RefernceEquals;String.Equals方法;String.Compare方法;String.CompareOrdinal方法。

    一.“==”操作符:String.Equals:ReferenceEquals 方法 1.在编程中实际上我们只需要这两种比较,c#中类型也就这两种 (1)值类型的比较:一般我们就是判断两个值类型实例各 ...