Менеджер Объектов В Magento 2

ObjectManager можно назвать одной из основных концепций, лежащих в основе конструкции Magento2, и она является совершенно новой по сравнению с Magento1. Если мы помним Magento1, то там для создания нужных нам для работы объектов мы использовали класс Mage, который предоставлял статические методы для создания разных типов объектов — будь то модели, модели ресурсов, помощники или для создания объектов, которые мы хотели иметь в одном экземпляре (метод Mage::getSingleton).

При создании Magento2 команда разработчиков отказалась от этой идеи и реализовала принцип внедрения зависимостей и сервисных контрактов.

Именно это сделало Magento2 таким гибким, легко настраиваемым и тестируемым.

Также наличие функционала, построенного на базе ObjectManager, позволяет иметь весь функционал по настройке поведения системы, который мы можем настроить с помощью файла конфигурации di.xml. Если глобально посмотреть на функциональность, которую реализует ObjectManager, то можно сказать, что это своего рода реализация DI-контейнера, который в мире PHP представлен как PSR-11, хотя сам ObjectManager не реализует напрямую Psr\Container\ContainerInterface ( и не имеет метода has, наличие которого предполагает Psr\Container\ContainerInterface).

Это централизованное средство создания и извлечения объектов.

Наличие такого централизованного класса для генерации необходимых объектов имеет следующие преимущества.

  • Нам не нужно вручную инициализировать и управлять объектами (также следует сказать, что ObjectManager используется для генерации объектов внутри классов Factory и Proxy, которые создаются посредством генерации кода)
  • Есть возможность через настройки указать, какую реализацию определенного интерфейса должен получить класс и использовать принцип инверсии зависимостей.

  • систему становится легче тестировать
  • можно использовать прокси-классы и фабричные классы
  • Ээкономия ресурсов сервера, так как часть объектов не переинициализируется, а ранее созданные объекты берутся из кэша (общая настройка)
Если рассмотреть последний пункт подробнее, то надо сказать, что сам класс Magento\Framework\ObjectManager\ObjectManager имеет защищенный атрибут $_sharedInstances = [].

Именно этот атрибут содержит объекты, которые не должны создаваться более одного раза и при запросе на их получение просто берет их из этого массива (кэша) по ключу — ключом является полное имя класса, включающее в себя пространство имен.

Но как именно класс ObjectManager узнает, какие классы следует поместить в этот массив? Все объекты, созданные с помощью ObjectManager, по умолчанию имеют настройкуshared=true. Но такое поведение можно изменить — для этого используйте специальную общую настройку в xml-файле.

Например, вы можете взять объявление классов слушателей (наблюдателей).

   

<observer name="legacy_model_save" instance="Magento\Framework\EntityManager\Observer\BeforeEntitySave" shared="false"/>

Такой класс будет создаваться каждый раз как новый объект. Также такая настройка доступна для объектов, которые передаются конструктору через конструкцию типа.

Как упоминалось выше, этот параметр по умолчанию имеет значение true для экономии ресурсов сервера.

Теперь я хотел бы сосредоточиться на процессе инициализации класса ObjectManager и на том, как он создает экземпляры объектов.

Здесь необходимо сделать оговорку, что ниже в статье процесс будет рассматриваться как применимый к приложению типа Http. Если мы посмотрим на файл index.php, то увидим, что он использует класс Magento\Framework\App\Bootstrap. И сначала вызывается его статический метод create, который принимает 2 параметра:

  • адрес корневого каталога проекта
  • массив параметров — $_SERVER + настройки адреса каталога
Внутри метода create вызывается статический метод createObjectManagerFactory, который создает экземпляр объекта класса Magento\Framework\App\ObjectManagerFactory и передает его конструктору класса Bootstrap, где он используется для создания объекта класса Magento\Framework\App\ObjectManagerFactory. Класс \ObjectManager. Именно этот объект впоследствии используется для создания экземпляров всех дальнейших используемых объектов.

Далее в методе Magento\Framework\App\Http::launch объект класса ObjectManager настраивается путем вызова метода Magento\Framework\App\ObjectManager::configure. Параметром этого метода является уже подготовленный к использованию массив настроек из файлов di.xml. Именно благодаря этим настройкам ObjectManager реализует такие возможности, как предпочтение, тип, виртуальный тип.

Сами эти настройки не хранятся в классе ObjectManager — он делегирует их использование классу Magento\Framework\ObjectManager\Config\Config, который реализует Magento\Framework\ObjectManager\ConfigInterface. Этот класс обрабатывает массив настроек из файлов di.xml и объединяет их по типам: Preference, Type, VirtualType и затем позволяет получить их в подготовленном виде.

Кроме того, именно этот класс хранит карту предпочтений и дает ObjectManager правильное имя создаваемого объекта.

Далее приложение использует 2 метода класса ObjectManager: create и get. Разница между этими методами в том, что метод create всегда создает новый объект переданного класса (можно сказать, что это реализация паттерна метода Factory), а метод get — при повторном запросе объекта класса, который уже создан ранее, просто вернет его из кеша.

Если рассмотреть эти методы подробнее, то они оба создают объекты через специальную фабрику (класс, реализующий интерфейс Magento\Framework\ObjectManager\FactoryInterface), которая в зависимости от режима работы приложения может быть представлена классами которые расположены в пространстве имен Magento\Framework\ ObjectManager\Factory. Такая фабрика получает через механизм отражения PHP аргументы конструктора требуемого класса и рекурсивно инициализирует их.

Затем эти подготовленные аргументы передаются в метод Magento\Framework\ObjectManager\Factory\AbstractFactory::createObject, который возвращает готовый к использованию объект. Далее ObjectManager может либо просто вернуть такой объект, либо сохранить его в кэше для дальнейшего использования, в зависимости от настроек, как указано выше.

Вам также следует обратить внимание на пространство имен Magento\Framework\ObjectManager\Code\Generator. Классы, находящиеся в нем, используются для создания классов Factory и Proxy, которые передаются пользовательским классам в качестве аргументов конструктора (Proxy должен быть указан в качестве аргумента конструктора через файл di.xml) и создаются с помощью механизма генерации пурпурного кода.

Прокси-классы, как следует из названия, используются для снижения нагрузки на сервер путем замены исходного класса его прокси-классом, который инициализирует исходный класс только в случае его вызова (реализация шаблона Прокси).

Фабричные классы используются для создания объектов в пользовательском коде, обычно объектов классов модели предметной области.

Сами классы Factory реализуют шаблон фабричного метода, имея общедоступный метод create, который внутренне вызывает ObjectManager и создает экземпляры объектов с помощью метода Magento\Framework\App\ObjectManager::create. Тег: #php #magento #magento 2

Вместе с данным постом часто просматривают: