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. 【AO笔记】有关TIN数据集的常用介绍

    写论文查了很多TIN的接口和属性,特此来记录一下. 转载请注明出处:博客园@秋意正寒,B站同名. 未完待续 1. Tin数据集在ArcGIS中的描述 Tin数据集在磁盘中,被ArcGIS以文件夹形式管 ...

  2. python数据处理excel和pdf,并打包成exe

    之前零散的用过一点python做数据处理,这次又遇到一个数据处理的小功能,因此,记录一下整个流程,方便以后查阅. 功能要求:读取excel,找指定的PDF文件的页数是否与excel中记录的一致 整个处 ...

  3. URL中包含url参数,(文件路径作为参数)

    用encodeURIComponent方法,把路径放在里面,可以防止斜杠被取消. 以下attachfiles是我的一个文件的绝对路径. window.location.href="${pag ...

  4. 微信小程序(三)页面跳转和图片滑动切换

    跳转部分: 在index2.wxml中,添加跳转函数,如下所示:

  5. java实现Windows记事本

    给大家分享下我之前的作品: 源文件下载: 链接:https://pan.baidu.com/s/1N45VsS9aVgmvhvYjRLxBrA  提取码:b9fg  源码: JF_Notpad.jav ...

  6. FFmpeg AVPacket相关主要函数介绍

    1.AVPacket相关函数介绍 操作AVPacket的函数大约有30个,主要分为:AVPacket的创建初始化,AVPacket中的data数据管理(clone,free,copy),AVPacke ...

  7. ubuntu16.04系统深度学习开发环境、常用软件环境(如vscode、wine QQ、 360wifi驱动(第三代暂无))搭建相关资料

    事后补充比较全面的(找对资料真的省一半功夫):https://www.jianshu.com/p/5b708817f5d8?from=groupmessage Ubuntu16.04 + 1080Ti ...

  8. centos7防火墙导致不能访问的

    CentOS 7.0默认使用的是firewall作为防火墙,使用iptables必须重新设置一下 1.直接关闭防火墙 systemctl stop firewalld.service #停止firew ...

  9. A Deep Learning-Based System for Vulnerability Detection(一)

    接着上一篇,讨论讨论具体步骤实现方法.步骤1-3分别在下面进行阐述,步骤4,6都是标准的,步骤5类似于步骤1-3. 结合这个图进行讨论详细步骤: 步骤1:提取库/API函数调用和程序片段 1.1将库/ ...

  10. IBM小练习

    '''例一:BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,如果我们将其做成一个属性,更便于理解) 成人的BMI数值: 过轻:低于18.5 正常:18.5-23.9 过重:24- ...