One of the most common questions when working with Magento 2 is: should I override a class with a preference, or use a plugin? The answer is almost always the same – use a plugin. But “almost” does a lot of work here. I explain the differences and show when a preference makes sense.
What is a Plugin (Interceptor)?
A plugin is an AOP (Aspect-Oriented Programming) mechanism in Magento 2. It lets you “wrap” an existing public method without overriding it. Three types available:
- before – runs before the method, can modify arguments
- after – runs after the method, can modify the result
- around – takes full control, calls (or skips) the original method
<?php
namespace Vendor\Module\Plugin;
use Magento\Catalog\Model\Product;
class ProductNamePlugin
{
public function afterGetName(Product $subject, string $result): string
{
return $result . ' - On Sale!';
}
}
Registration in di.xml:
<type name="Magento\Catalog\Model\Product">
<plugin name="vendor_module_product_name"
type="Vendor\Module\Plugin\ProductNamePlugin"
sortOrder="10"/>
</type>
What is a Preference?
A preference is a literal replacement of class A with class B in the DI container.
<preference for="Magento\Catalog\Model\Product"
type="Vendor\Module\Model\Product"/>
Why is a Plugin almost always better?
Key problem with preferences: there can only be one preference for a given class. If you and a third-party extension both set a preference for the same class – one silently wins. Plugins stack – all of them run, ordered by sortOrder.
When does a Preference make sense?
- You need to override a private or protected method – plugins only work on public methods.
- You need to change the constructor – plugins cannot modify
__construct(). - You are implementing an interface differently
- The class is marked
@api
Watch out for the “around” plugin
If you forget to call $proceed(), the original code and all queued plugins will never run. Use around only when you genuinely need to conditionally skip the original method.
Summary – a short rule
Before reaching for a preference, ask: would a plugin not be enough? In 90% of cases it is. A preference leaves behind a trail that is hard to debug during Magento upgrades.
