
Magento2.3.5学习重写核心类
在magento2.3.5版本中学习三种重写核心的的方法,(插件,依赖注入,事件观察者)以及三者的优缺点,各自的使用场景
·
在Magento 2中,重写(Override)核心类的方法通常有三种:通过插件(Plugin)、通过依赖注入(Preference)、和通过事件观察者(Event Observer)。每种方法适用于不同的场景,以下是对这三种方法的详细说明和使用方式。
例如要重写Product类可以通过这三种方式来实现
1. 插件(Plugin)
插件也被称为“拦截器”,是Magento 2推荐的重写方法。通过插件可以在原方法执行前后或者绕过原方法来添加自定义逻辑,而不会影响原始方法的实现。
插件使用步骤
1.创建 di.xml
配置文件:
- 在 app/code/Vendor/HelloWorld/etc/di.xml 中添加插件配置:
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <type name="Magento\Catalog\Model\Product"> <plugin name="vendor_helloworld_product_plugin" type="Vendor\HelloWorld\Plugin\ProductPlugin" sortOrder="10" disabled="false" /> </type> </config>
type
:要重写的类(目标类),如Magento\Catalog\Model\Product
。plugin name
:插件的名称,命名需唯一。type
:自定义插件类的路径。
2.创建插件类:
- 在 app/code/Vendor/HelloWorld/Plugin/ProductPlugin.php 中创建插件类:
<?php namespace Vendor\HelloWorld\Plugin; use Magento\Catalog\Model\Product; use Psr\Log\LoggerInterface; class ProductPlugin { protected $logger; public function __construct(LoggerInterface $logger) { $this->logger = $logger; } public function beforeSave(Product $subject) { $name = $subject->getName(); $subject->setName(strtoupper($name)); } public function afterSave(Product $subject, $result) { $id = $subject->getId(); if ($id) { $this->logger->info('Product Plugin saved with ID: ' . $id); } else { $this->logger->info('Nothing'); } return $result; } public function aroundSave(Product $subject, callable $proceed) { $name = $subject->getName(); $subject->setName('Before Save: ' . $name); $result = $proceed(); $id = $subject->getId(); $product = $subject->load($id); $new_name = $product->getName(); $this->logger->info('Set New Name over saved with new name: ' . $new_name); return $result; } }
- beforeSave方法:在目标方法执行之前触发,获取创建商品的名称,并且将名称进行大小写修改
- afterSave方法:在目标方法执行之后触发,并可以修改返回结果,获取创建商品的id编号,然后将存储记录通过log保存到日志中
- aroundSave方法:可以控制目标方法的执行流程,并决定是否调用原方法,在保存之前获取商品的名称,并且将商品的名称加上前缀,然后执行保存原方法,执行结束之后,获取新名称,并且将这条信息进行log记录
插件适用场景
- 想在不修改原始代码的情况下对某个类的方法进行增强或修改。
- 插件机制能够减少代码耦合,适合用于重写模型类、服务类、Block类中的方法。
2. 依赖注入(Preference)
依赖注入是一种直接替换类的方式,适用于完全重写类的场景,但不推荐用来重写大部分逻辑复杂的类,因为这种方式会完全替换原类,可能带来兼容性问题。
Preference 使用步骤
1.创建 di.xml
配置文件:
- 在 app/code/Vendor/HelloWorld/etc/di.xml 中添加插件配置:
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="Magento\Catalog\Model\Product" type="Vendor\HelloWorld\Model\Rewrite\Product" /> </config>
- for:目标类名,即要替换的核心类。
- type:替换后的自定义类。
2.创建自定义类:
- 在 app/code/Vendor/HelloWorld/Model/Rewrite/Product.php 中创建自定义类:
<?php namespace Vendor\HelloWorld\Model\Rewrite; class Product extends \Magento\Catalog\Model\Product { public function getName() { // 调用父类的 getName 方法 $name = parent::getName(); // 添加自定义逻辑,例如:添加一个后缀 return $name . ' - Custom Suffix'; } public function getPrice() { $price = parent::getPrice(); return $price * 0.8; } }
- getName方法:通过调用父类的getName获取商品名称,并且为商品名称添加后缀
- getPrice方法:通过调用父类的getPrice获取商品的价格,并且对商品价格进行修改
Preference 适用场景
- 当你需要完全重写类的所有方法时使用。
- 不推荐用于重写Magento核心模块类的方法,而更多用于自定义模块间的替换。
3. 事件观察者(Event Observer)
事件观察者是一种基于事件机制的重写方式,可以在特定事件触发时执行自定义逻辑,而不直接修改核心类或方法。
事件观察者使用步骤
1.定义事件观察者配置文件 events.xml:
- 在 app/code/Vendor/HelloWorld/etc/events.xml 中添加如下配置:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<!-- 监听catalog_product_save_after事件 -->
<event name = "catalog_product_save_after">
<observer name = "vendor_helloworld_product_save_after_observer" instance="Vendor\HelloWorld\Observer\ProductSaveAfterObserver" />
</event>
</config>
- event name:要观察的事件名称。(事件名称:catalog_product_save_after)
- observer name:观察者的名称。(观察者名称:vendor_helloworld_product_save_after_observer)
- instance:自定义观察者类的路径。(路径:Vendor\HelloWorld\Observer\ProductSaveAfterObserver)
2.创建观察者类:
- 在 app/code/Vendor/HelloWorld/Observer/ProductSaveAfterObserver.php 中创建观察者类:
<?php
namespace Vendor\Helloworld\Observer;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Psr\Log\LoggerInterface;
class ProductSaveAfterObserver implements ObserverInterface
{
protected $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
public function execute(Observer $observer)
{
// 获取保存后的产品对象
$product = $observer->getEvent()->getProduct();
// 在日志中记录产品ID 记录到log/system.log
$this->logger->info('Product saved with ID: ' . $product->getId());
}
}
- 在 execute() 方法中,可以通过 $observer->getEvent()->getProduct() 获取到当前事件中的 Product 对象,并对其进行操作,将Product对象的id记录到log日志里面。
事件观察者适用场景
- 当需要在特定事件(如保存、删除等)发生时进行额外操作。
- 事件观察者不会直接修改核心类,但能够扩展核心类行为。
4.三种重写方式的比较
方法 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
插件 (Plugin) | 可在方法执行前后或绕过原方法,不影响原始代码 | 复杂类重写时难以管理;某些方法无法通过插件拦截 | 针对单个方法进行增强或修改 |
依赖注入 (Preference) | 完全替换目标类,适用于自定义模块间的替换 | 可能导致不兼容,直接替换不安全 | 完全替换类的实现 |
事件观察者 (Event Observer) | 基于事件的机制,能在特定操作发生时触发,便于扩展 | 无法直接重写方法,只能进行事件相关的操作 | 针对事件的处理,例如保存前、保存后等操作 |
5.具体应用场景和选择建议
- 如果只想修改某个类中的个别方法,优先选择 插件(Plugin)。
- 如果需要在某个事件(如保存、删除)中执行额外逻辑,使用 事件观察者(Event Observer)。
- 如果希望完全替换某个类的实现,可以考虑 依赖注入(Preference),但要慎重使用。
效果图:
以上就是Magento2.3.5中重写核心类的三种方法,下一篇学习创建一个在magento中创建一个cron定时任务
更多推荐
所有评论(0)