Skip to content

Commit

Permalink
Merge pull request #396 from goaop/feature/optimize-class-hierarchy
Browse files Browse the repository at this point in the history
Drop BaseAdvice class to speed up class initialization
  • Loading branch information
lisachenko committed May 19, 2018
2 parents 99fc91f + 8ac44af commit efe2568
Show file tree
Hide file tree
Showing 10 changed files with 169 additions and 194 deletions.
156 changes: 156 additions & 0 deletions src/Aop/Framework/AbstractInterceptor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
<?php
declare(strict_types = 1);
/*
* Go! AOP framework
*
* @copyright Copyright 2011, Lisachenko Alexander <lisachenko.it@gmail.com>
*
* This source file is subject to the license that is bundled
* with this source code in the file LICENSE.
*/

namespace Go\Aop\Framework;

use Closure;
use Go\Core\AspectKernel;
use ReflectionFunction;
use ReflectionMethod;
use Serializable;
use Go\Aop\Intercept\Interceptor;

/**
* Base class for all framework interceptor implementations
*
* This class describe an action taken by the interceptor at a particular joinpoint.
* Different types of interceptors include "around", "before" and "after" advices.
*
* Around interceptor is an advice that surrounds a joinpoint such as a method invocation. This is the most powerful
* kind of advice. Around advices will perform custom behavior before and after the method invocation. They are
* responsible for choosing whether to proceed to the joinpoint or to shortcut executing by returning their own return
* value or throwing an exception.
*
* After and before interceptors are simple closures that will be invoked after and before main invocation.
*
* Framework models an interceptor as an PHP-closure, maintaining a chain of interceptors "around" the joinpoint:
* public function (Joinpoint $joinPoint)
* {
* echo 'Before action';
* // call chain here with Joinpoint->proceed() method
* $result = $joinPoint->proceed();
* echo 'After action';
*
* return $result;
* }
*/
abstract class AbstractInterceptor implements Interceptor, OrderedAdvice, Serializable
{
/**
* Local cache of advices for faster unserialization on big projects
*
* @var Closure[]
*/
protected static $localAdvicesCache = [];

/**
* Pointcut expression string which was used for this interceptor
*/
protected $pointcutExpression;

/**
* Closure to call
*/
protected $adviceMethod;

/**
* Advice order
*/
private $adviceOrder;

/**
* Default constructor for interceptor
*/
public function __construct(Closure $adviceMethod, int $adviceOrder = 0, string $pointcutExpression = '')
{
$this->adviceMethod = $adviceMethod;
$this->adviceOrder = $adviceOrder;
$this->pointcutExpression = $pointcutExpression;
}

/**
* Serialize advice method into array
*/
public static function serializeAdvice(Closure $adviceMethod): array
{
$refAdvice = new ReflectionFunction($adviceMethod);

return [
'method' => $refAdvice->name,
'aspect' => get_class($refAdvice->getClosureThis())
];
}

/**
* Unserialize an advice
*
* @param array $adviceData Information about advice
*/
public static function unserializeAdvice(array $adviceData): Closure
{
$aspectName = $adviceData['aspect'];
$methodName = $adviceData['method'];

if (!isset(static::$localAdvicesCache["$aspectName->$methodName"])) {
$aspect = AspectKernel::getInstance()->getContainer()->getAspect($aspectName);
$refMethod = new ReflectionMethod($aspectName, $methodName);
$advice = $refMethod->getClosure($aspect);

static::$localAdvicesCache["$aspectName->$methodName"] = $advice;
}

return static::$localAdvicesCache["$aspectName->$methodName"];
}

/**
* Returns the advice order
*/
public function getAdviceOrder(): int
{
return $this->adviceOrder;
}

/**
* Getter for extracting the advice closure from Interceptor
*/
public function getRawAdvice(): Closure
{
return $this->adviceMethod;
}

/**
* Serializes an interceptor into string representation
*
* @return string the string representation of the object or null
*/
public function serialize()
{
$vars = array_filter(get_object_vars($this));
$vars['adviceMethod'] = static::serializeAdvice($this->adviceMethod);

return serialize($vars);
}

/**
* Unserialize an interceptor from the string
*
* @param string $serialized The string representation of the object.
* @return void
*/
public function unserialize($serialized)
{
$vars = unserialize($serialized);
$vars['adviceMethod'] = static::unserializeAdvice($vars['adviceMethod']);
foreach ($vars as $key => $value) {
$this->$key = $value;
}
}
}
2 changes: 1 addition & 1 deletion src/Aop/Framework/AfterInterceptor.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
*
* @api
*/
final class AfterInterceptor extends BaseInterceptor implements AdviceAfter
final class AfterInterceptor extends AbstractInterceptor implements AdviceAfter
{
/**
* @inheritdoc
Expand Down
2 changes: 1 addition & 1 deletion src/Aop/Framework/AfterThrowingInterceptor.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
*
* @api
*/
final class AfterThrowingInterceptor extends BaseInterceptor implements AdviceAfter
final class AfterThrowingInterceptor extends AbstractInterceptor implements AdviceAfter
{
/**
* @inheritdoc
Expand Down
2 changes: 1 addition & 1 deletion src/Aop/Framework/AroundInterceptor.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
*
* @api
*/
final class AroundInterceptor extends BaseInterceptor implements AdviceAround
final class AroundInterceptor extends AbstractInterceptor implements AdviceAround
{
/**
* @inheritdoc
Expand Down
99 changes: 0 additions & 99 deletions src/Aop/Framework/BaseAdvice.php

This file was deleted.

82 changes: 0 additions & 82 deletions src/Aop/Framework/BaseInterceptor.php

This file was deleted.

2 changes: 1 addition & 1 deletion src/Aop/Framework/BeforeInterceptor.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
*
* @api
*/
final class BeforeInterceptor extends BaseInterceptor implements AdviceBefore
final class BeforeInterceptor extends AbstractInterceptor implements AdviceBefore
{
/**
* @inheritdoc
Expand Down
2 changes: 1 addition & 1 deletion src/Aop/Framework/DeclareErrorInterceptor.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
* This interceptor can be used as active replacement for the "deprecated" tag or to notify about
* probable issues with specific method.
*/
class DeclareErrorInterceptor extends BaseInterceptor
class DeclareErrorInterceptor extends AbstractInterceptor
{

/**
Expand Down
Loading

0 comments on commit efe2568

Please sign in to comment.