Magento 2 Plugin - Interceptor - Magento 2插件 - 拦截器-插件开发
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插件无法使用?
- 在Magento \ Framework \ Interception之前实例化的对象是自我引导运行的;
- 最后的方法;
- 最后的类;
- 任何包含至少一个最终公共方法的类;
- 非 Public 方法(Non-public methods);
- 类方法(如静态方法);
- __construct;
- 虚拟类型(Virtual types);
3.创建Magento 2新插件的指南
- 在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{ }
- 在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);
}
} 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插件 - 拦截器-插件开发的更多相关文章
- Mybatis拦截器执行过程解析
上一篇文章 Mybatis拦截器之数据加密解密 介绍了 Mybatis 拦截器的简单使用,这篇文章将透彻的分析 Mybatis 是怎样发现拦截器以及调用拦截器的 intercept 方法的 小伙伴先按 ...
- Mybatis那些事-拦截器(Plugin+Interceptor)
作者:yhjyumi的专栏 数据权限实现(Mybatis拦截器+JSqlParser) Mybatis的拦截器实现机制,使用的是JDK的InvocationHandler. 当我们调用Paramete ...
- mybatis Interceptor拦截器代码详解
mybatis官方定义:MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis ...
- 过滤器(Filter)与拦截器(Interceptor )区别
目录 过滤器(Filter) 拦截器(Interceptor) 拦截器(Interceptor)和过滤器(Filter)的区别 拦截器(Interceptor)和过滤器(Filter)的执行顺序 拦截 ...
- Flume 拦截器(interceptor)详解
flume 拦截器(interceptor)1.flume拦截器介绍拦截器是简单的插件式组件,设置在source和channel之间.source接收到的事件event,在写入channel之前,拦截 ...
- CXF之五 拦截器Interceptor
拦截器(Interceptor)是CXF功能最主要的扩展点,可以在不对核心模块进行修改的情况下,动态添加很多功能.拦截器和JAX-WS Handler.Filter的功能类似,当服务被调用时,就会创建 ...
- Hibernate拦截器(Interceptor)与事件监听器(Listener)
拦截器(Intercept):与Struts2的拦截器机制基本一样,都是一个操作穿过一层层拦截器,每穿过一个拦截器就会触发相应拦截器的事件做预处理或善后处理. 监听器(Listener):其实功能与拦 ...
- MVC框架的插件与拦截器基础
自制MVC框架的插件与拦截器基础 上篇谈到我自己写的MVC框架,接下来讲讲插件及拦截器! 在处理一些通用的逻辑最好把它封装一个插件或者拦截器,以便日后可以直接拿过来直接使用.在我的框架中可以通过继承以 ...
- CXF实战之拦截器Interceptor(四)
拦截器(Interceptor)是CXF功能最基本的扩展点,能够在不正确核心模块进行改动的情况下.动态加入非常多功能.拦截器和JAX-WS Handler.Filter的功能相似,当服务被调用时.就会 ...
随机推荐
- 欧洲AI规范先行,值得肯定与借鉴 --- 我看欧盟发布AI道德规范
欧洲AI规范先行,值得肯定与借鉴 --- 我看欧盟发布AI道德规范 [事件回放] 近日,据外媒报道,欧盟委员会(EC)任命的人工智能高级专家小组发布了AI开发和使用的道德草案,内容长达37页,提出可信 ...
- 如何把activity当成dialog
在工作中有时候需要把activity当成dialog使用,其实做法挺简单的. 1.设置activity的style <style name="DialogTheme" par ...
- linux内核数据结构之kfifo【转】
1.前言 最近项目中用到一个环形缓冲区(ring buffer),代码是由linux内核的kfifo改过来的.缓冲区在文件系统中经常用到,通过缓冲区缓解cpu读写内存和读写磁盘的速度.例如一个进程A产 ...
- zabbix忘记admin登录密码重置密码
问题描述: 有时候忘记admin的密码了,因为账号太多 解决方案: 1.zabbix连接的是mysql数据库 [root@localhost /]# mysql -uroot -pAbc123 #-u ...
- 我认知的javascript之作用域和闭包
说到javascript,就不得不说javascript的作用域和闭包:当然,还是那句老话,javascript在网上都说得很透彻了,我也就不过多的强调了: 作用域:javascript并没有像其他的 ...
- json 解析错误的问题
“/”应用程序中的服务器错误. 未能加载文件或程序集“Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe ...
- 安装和使用 memcached
memcached 和 Grails,第 1 部分:安装和使用 memcached 学习 memcached 命令并评估缓存性能 本文是系列文章的第 1 部分,主要介绍 memcached 和 Gra ...
- git添加/删除远程仓库
注意:仓库只有管理员建的你才有权限上传,不然自己建的也没用,没权限上传 1.远程仓库路径查询 git remote -v 2.添加远程仓库 git remote add origin <你的项目 ...
- c++面经积累<2>
4.类成员初始化方式:列表初始化和赋值初始化 赋值初始化通过在函数体内进行赋值,列表初始化,在构造函数后面加上冒号,使用初始化列表进行初始化.在函数体内进行初始化,是在所有的数据成员被分配内存空间后进 ...
- 20175229许钰玮 2018-2019-2《Java程序设计》结对编程项目-四则运算 第一周 阶段性总结
20175229许钰玮 2018-2019-2<Java程序设计>结对编程项目-四则运算 第一周 阶段性总结 需求分析 自动生成四则运算题目(加.减.乘.除). 既可以用前缀算法(波兰算法 ...