I recently wrote a post about Aspect Oriented Programming, and how developers can use it within Magento 2. However, I didn’t cover anything about what Magento 2 is actually doing in the background. How exactly is it providing the Plugin?

Interceptors are how Magento 2’s object system implements the plugin system.

In theory, you don’t need to worry about how Magento provides the underlying plugin system in order to use it.

When you ask Magento for an object, it may return an interceptor, or it might return your referenced class.

How it’s implemented

If a class has a plugin configured, the object manager will return an interceptor.

Magento handles the delivery of an interceptor different ways depending on how your environment is configured.

Production Mode

In production mode, Magento will look through your solution during compilation, and create interceptors for plugins where required.

Magento handles plugin creation with a separate PHP autoloader. If a developer triggers a PHP autoload event, and the composer based autoloader can’t find the class file, a second registered autoloader is called:

Magento\Framework\Code\Generator\Autoloader

So, what’s happening here?

Magento is making a call to Magento\Framework\Code\Generator::generateClass.

As you can see from the code above, after name matching, it checks to see if there is any reason that the generation should be skipped.

Let’s take a look at an example.

We’re going to take a look at vendor/magento/module-customer/Model/Plugin/AllowedCountries.php. As you can see, we have a before method called on getAllowedCountries.

Magento creates an interceptor, thus:

Magento is extending the original class to allow our additional code to run. It returns the Interceptor class rather than the original.

This explains a few of the limitations listed in the previous article, such as why you cannot use a Plugin on a class with a final method, or on static method calls.

Developer Mode

In developer mode, where everything is done on the fly, the following code is run:

From vendor/magento/framework/Interception/ObjectManager/Config/Developer.php

Magento internally uses the vendor/magento/framework/Interception/ObjectManager/InterceptableValidator class in order to validate an interceptor.

Image Credit: Ferrari 250 Inter