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. EditText超出字数限制,给用户提示

    当我们在Editext输入内容的时候,检测如果超过限制的长度无法输入内容,并且给用户提示. 首先我想到了下面的方法: editText.addTextChangedListener(new TextW ...

  2. C#:在匿名方法中捕获外部变量

    先来一段代码引入主题.如果你可以直接说出代码的输出结果,说明本文不适合你.(代码引自<深入理解C#>第三版) class Program { private delegate void T ...

  3. Java 8 的Lambda表达式

    第一次看到用lambda表达式写出来的Java代码时,我对这种神秘的语法感到非常不理解,认为这样的Java搞得不可读.没有专门的去学习和认识,今天花了几个小时写了示例的练习后,我开心的看到了更清晰的J ...

  4. kylin简单优化cube

    优化Cube 层次结构 理论上,对于N维,你最终会得到2 ^ N维组合.但是对于某些维度组,不需要创建这么多组合.例如,如果您有三个维度:洲,国家,城市(在层次结构中,“更大”维度首先出现).在深入分 ...

  5. PHP生成PDF并转换成图片爬过的坑

    需求描述:根据订单通过模板合同生成新的PDF合同通过e签宝签约后转为图片给用户下载. 需求整理: 1.如何生成PDF文件:使用TCPDF扩展生成.思考: ⑴为了方便将模板中的固定占位符替换为订单中的内 ...

  6. Thread中yield方法

    先上一段代码 public class YieldExcemple { public static void main(String[] args) { Thread threada = new Th ...

  7. he

    弄好这个网站---to thi tha think 好这个---, 很温馨 那时候我还在看. 前一段时候看yibenhaoshu,走出来的才是理性,所以现在才是理性的看待的. 回头再看看两年前的事情, ...

  8. Scalability of Kafka Messaging using Consumer Groups

    May 10, 2018 By Suhita Goswami No Comments Categories: Data Ingestion Flume Kafka Use Case Tradition ...

  9. CentOS 7 增加磁盘分区挂载(lvm)

    1.查看主机现有磁盘情况 # fdisk -l 现在主机中存在一块8G的磁盘sdb,尚未分区挂载,所以需将磁盘进行分区挂载. 2.对磁盘进行分区 # fdisk /dev/sdb   (选择要操作分区 ...

  10. SpringBoot四大核心

    auto-configuration.starters.cli.actuator