여기에 답변이 있습니다
특정 경우에 프록시 클래스가 사용되는 이유는 무엇입니까?
"SetConversionValueObserver"클래스 용으로 작성된 코드 아래를 자세히 살펴보면 Google Adwards가 "반품"상태가 아니고 "반품"주문이없는 경우입니다. 즉, 주문 ID가 존재하고 Google 애드워즈가 활성화 된 경우에만 주문 수집 개체가 생성됩니다. 실제 주문 수집 클래스를 삽입하면 객체 관리자가 Google 애드워즈가 활성화되어 있지 않고 주문 성공 페이지가 느려지는 것을 알지 못하고 부모 클래스 객체로 컬렉션 객체를 만듭니다. 따라서 프록시를 사용하는 온 디맨드 오브젝트를 더 잘 작성하십시오. /vendor/magento/module-google-adwords/Observer/SetConversionValueObserver.php
/**
* Set base grand total of order to registry
*
* @param \Magento\Framework\Event\Observer $observer
* @return \Magento\GoogleAdwords\Observer\SetConversionValueObserver
*/
public function execute(\Magento\Framework\Event\Observer $observer)
{
if (!($this->_helper->isGoogleAdwordsActive() && $this->_helper->isDynamicConversionValue())) {
return $this;
}
$orderIds = $observer->getEvent()->getOrderIds();
if (!$orderIds || !is_array($orderIds)) {
return $this;
}
$this->_collection->addFieldToFilter('entity_id', ['in' => $orderIds]);
$conversionValue = 0;
/** @var $order \Magento\Sales\Model\Order */
foreach ($this->_collection as $order) {
$conversionValue += $order->getBaseGrandTotal();
}
$this->_registry->register(
\Magento\GoogleAdwords\Helper\Data::CONVERSION_VALUE_REGISTRY_NAME,
$conversionValue
);
return $this;
}
일반적으로 언제 프록시 클래스를 사용해야합니까?
-객체 생성이 비싸고 클래스 생성자가 특히 자원 집약적이라고 느낄 때 프록시 클래스를 주입하십시오. -객체 생성으로 인한 불필요한 성능 영향을 원하지 않는 경우 -특정 조건에서 특정 메소드를 호출 할 때 항상 객체 생성이 발생해야하는 느낌이들 때. 예를 들어 레이아웃 생성자는 리소스를 많이 사용합니다.
실제 레이아웃 생성자 대 레이아웃 / 프록시
public function __construct(
Layout\ProcessorFactory $processorFactory,
ManagerInterface $eventManager,
Layout\Data\Structure $structure,
MessageManagerInterface $messageManager,
Design\Theme\ResolverInterface $themeResolver,
Layout\ReaderPool $readerPool,
Layout\GeneratorPool $generatorPool,
FrontendInterface $cache,
Layout\Reader\ContextFactory $readerContextFactory,
Layout\Generator\ContextFactory $generatorContextFactory,
AppState $appState,
Logger $logger,
$cacheable = true,
SerializerInterface $serializer = null
) {
$this->_elementClass = \Magento\Framework\View\Layout\Element::class;
$this->_renderingOutput = new \Magento\Framework\DataObject();
$this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
$this->_processorFactory = $processorFactory;
$this->_eventManager = $eventManager;
$this->structure = $structure;
$this->messageManager = $messageManager;
$this->themeResolver = $themeResolver;
$this->readerPool = $readerPool;
$this->generatorPool = $generatorPool;
$this->cacheable = $cacheable;
$this->cache = $cache;
$this->readerContextFactory = $readerContextFactory;
$this->generatorContextFactory = $generatorContextFactory;
$this->appState = $appState;
$this->logger = $logger;
}
프록시 생성자, 호출 된 부모 생성자 및 레이아웃 클래스 이름을 전달하여 메서드가 호출 될 때 실제 객체 생성이 이루어 지도록 살펴보십시오.
/**
* Proxy constructor
*
* @param \Magento\Framework\ObjectManagerInterface $objectManager
* @param string $instanceName
* @param bool $shared
*/
public function __construct(
\Magento\Framework\ObjectManagerInterface $objectManager,
$instanceName = \Magento\Framework\View\Layout::class,
$shared = true
) {
$this->_objectManager = $objectManager;
$this->_instanceName = $instanceName;
$this->_isShared = $shared;
}
프록시 클래스에는 요청시 객체를 만드는 방법이 있으며 _subject는 전달 된 클래스의 객체입니다.
/**
* Get proxied instance
*
* @return \Magento\Framework\View\Layout
*/
protected function _getSubject()
{
if (!$this->_subject) {
$this->_subject = true === $this->_isShared
? $this->_objectManager->get($this->_instanceName)
: $this->_objectManager->create($this->_instanceName);
}
return $this->_subject;
}
그리고 _subject를 사용하여 메소드를 호출했습니다.
/**
* {@inheritdoc}
*/
public function setGeneratorPool(\Magento\Framework\View\Layout\GeneratorPool $generatorPool)
{
return $this->_getSubject()->setGeneratorPool($generatorPool);
}