왜 protected
메소드 용 플러그인을 만들 수 없는지 궁금했습니다 . 이 코드는 다음과 Magento\Framework\Interception\Code\Generator\Interceptor
같습니다.
protected function _getClassMethods()
{
$methods = [$this->_getDefaultConstructorDefinition()];
$reflectionClass = new \ReflectionClass($this->getSourceClassName());
$publicMethods = $reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC);
foreach ($publicMethods as $method) {
if ($this->isInterceptedMethod($method)) {
$methods[] = $this->_getMethodInfo($method);
}
}
return $methods;
}
메소드가 public
인터셉트되기 전에 있는지 확인합니다 . 그것은 쉽게를 작성하여 변경 될 수 preference
에서 di.xml
다음과 같이 물론, 자신의 모듈 :
<?xml version="1.0"?>
<config>
<preference for="Magento\Framework\Interception\Code\Generator\Interceptor" type="MyVendor\MyModule\Model\MyInterceptorModel" />
</config>
및 재기록 _getClassMethods
(가)로 \ReflectionMethod::IS_PUBLIC
변경 \ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED
하는 방법의 내부.
그러나 원래 메서드 정의에서 보호 된 메서드를 가로 챌 수없는 이유가 무엇입니까? 성능에 큰 영향을 미치거나 타사 모듈이 Magento 논리를 “지저분하게”만들도록 허용하는 것과 같은 다른 이유가 있습니까?
답변
Magento 문서에 따르면 보호 된 메소드에서 플러그인을 사용하는 것은 “가능한”것이 아닙니다.
( http://devdocs.magento.com/guides/v2.0/extension-dev-guide/plugins.html )
다음에 플러그인을 적용 할 수 없습니다.
- 최종 방법
- 최종 수업
- 하나 이상의 최종 공개 메소드를 포함하는 모든 클래스
- 비공개 방법
- 클래스 메서드 (정적 메서드 등)
- __ 구문 가상 유형
하지만 당신의 포인트에 따라, 올바른 ___callPlugins
에서 정의Magento\Framework\Interception\Interceptor
보호 된 방법을 사용하는 데 아무런 문제가 없습니다.
내 첫 번째 추측은 Magento가 보호 된 메소드를 다시 작성하고 ___callPlugins
각 메소드를 호출해야하기 때문에 높은 코드 복잡성을 피하기 위해 제한했습니다 .IMHO 가 크게 느려질 것입니다.
그러나 진정한 이유는 논리적 일관성에 있다고 생각합니다. 플러그인은 내부 동작을 다시 쓰지 않고 클래스 메소드 output / input을 변경하는 데 사용해야하므로 공용 메소드에만 액세스해야합니다.
내부 동작을 다시 쓰려면 환경 설정을 사용해야합니다. 말된다.
답변
Anton Krill의 프레젠테이션에서 올바르게 기억한다면 기술적으로 보호 된 방법은 가로 챌 수 있지만 “보호 된”방법의 목적을 상실한 것입니다.
자동 생성 된 인터셉터 클래스는 원래 클래스를 확장하여 보호 된 메소드에 액세스 할 수 있습니다.
그러나 … 보호 된 메소드는 클래스 외부에서 사용할 수 없습니다.
따라서 그것은 제한보다 더 많은 결정입니다.
답변
마 젠토와 관련이없는 OOPS 보안 기능입니다.
모든 클래스에서 public으로 레이블이 지정된 공용 메소드를 사용할 수 있습니다. protected로 표시된 보호 된 메소드는 서브 패키지 및 친숙한 클래스에서 사용 가능하며, 동일한 클래스의 클래스입니다. 친숙한 클래스에는 아무것도 표시되지 않은 친숙한 메서드 (예 : 기본값)를 사용할 수 있습니다. 개인 메서드는 클래스 자체에서만 사용할 수 있습니다.
원인:
1) 보호 된 메소드는 상속 2 단계에서 액세스 할 수 없습니다.
예제 : 클래스 A와 클래스 B의 두 클래스를 동일한 패키지로 예를 들어 보겠습니다.
클래스 B는 상속 A 클래스의 공용 메소드뿐만 아니라 상속 만 보호 할 수 있습니다.