magento2中的设计模式-Proxy代理模式详解

magento2中的proxy是一种设计模式,比较难于理解,本篇内容将为大家介绍magento2中的代理模式:proxy

当对象创建成本很高,并且类的构造函数占用了大量资源时,就会使用代理类。为了避免不必要的性能影响,

Magento使用Proxy类将给定的类型变成它们的延迟加载版本。

在所有Magento di.xml文件中快速查找\Proxy</argument>字符串可以发现该字符串出现了一百多次。

可以说,Magento在其代码中广泛使用代理。

<MAGENTO_DIR>/module-customer/etc/di.xml下的类型定义是使用代理的一个很好的例子:

<type name="Magento\Customer\Model\Session">
    <arguments>
        <argument name="configShare" xsi:type="object">Magento\Customer\Model\Config\Share\Proxy</argument>
        <argument name="customerUrl" xsi:type="object">Magento\Customer\Model\Url\Proxy</argument>
        <argument name="customerResource" xsi:type="object">Magento\Customer\Model\ResourceModel\Customer\Proxy</argument>
        <argument name="storage" xsi:type="object">Magento\Customer\Model\Session\Storage</argument>
        <argument name="customerRepository" xsi:type="object">Magento\Customer\Api\CustomerRepositoryInterface\Proxy</argument>
    </arguments>
</type>

如果我们查看Magento\Customer\Model\Session类型的构造函数,我们可以看到四个参数

(configShare、customerUrl、customerResource和customerRepository)中,

没有一个在PHP文件中声明为Proxy。它们是通过di.xml重写的。

这些代理类型还不真正存在,因为Magento依赖注入(di)编译过程创建了它们。

它们是在生成的目录下自动生成的。

编译后,可以在生成的/code/Magento/Customer/Model/Url/Proxy.php

文件下轻松找到Magento\Customer\Model\Url\Proxy.php类型。

让我们局部来看一下:

<?php
class Proxy extends\ Magento\ Customer\ Model\ Url implements\ Magento\ Framework\ ObjectManager\ NoninterceptableInterface {
    public function __construct(\Magento\ Framework\ ObjectManagerInterface $objectManager, $instanceName = '\\Magento\\Customer\\Model\\Url', $shared = true) {
        $this - > _objectManager = $objectManager;
        $this - > _instanceName = $instanceName;
        $this - > _isShared = $shared;
    }
    public function __sleep() {
        return ['_subject', '_isShared', '_instanceName'];
    }
    public function __wakeup() {
        $this - > _objectManager = \Magento\ Framework\ App\ ObjectManager::getInstance();
    }
    public function __clone() {
        $this - > _subject = clone $this - > _getSubject();
    }
    protected function _getSubject() {
        if (!$this - > _subject) {
            $this - > _subject = true === $this - > _isShared ? $this - > _objectManager - > get($this - > _instanceName) : $this - > _objectManager - > create($this - > _instanceName);
        }
        return $this - > _subject;
    }
    public function getLoginUrl() {
        return $this - > _getSubject() - > getLoginUrl();
    }
    public function getLoginUrlParams() {
        return $this - > _getSubject() - > getLoginUrlParams();
    }
}

Proxy类的组成显示了它包装原始Magento\Customer\Model\Url类型的机制。这意味着,在整个Magento中,

每次请求Magento\Customer\Model\Url类型时,

Magento\Customer\Module\Url\Proxy都会被传递。与原始类型的__construct方法(可能会影响性能)不同,

自动生成代理的__construction方法是轻量级的。这消除了可能的性能瓶颈。_getSubject方法用于在调用任何原始类型的公共方法时,

实例化/延迟加载原始类型。

例如,对getLoginUrl方法的调用将通过代理。

Magento生成的每个代理都实现了Magento\Framework\ObjectManager\NoninterceptableInterface。

尽管接口本身是空的,但它被用作标识代理的标记,

我们不需要为其生成拦截器(插件)。

class Customer {
    public
    function __construct(\Magento\ Customer\ Model\ Url\ Proxy $customerUrl) { //...    }}

然而,这种做法是一种糟糕的做法。正确执行此操作的方法是使用原始Magento\Customer\Model\Url类型指定__construct,

然后按如下方式添加di.xml:

<type name="Magelicious\Core\Model\Customer">
    <arguments>
        <argument name="customerUrl" xsi:type="object">Magento\Customer\Model\Url\Proxy</argument>
    </arguments>
</type>

以上内容来源于码小课:

 码小课提供magento2全栈开发内容,欢迎大家访问。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值