Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AOP特性微调 #95

Merged
merged 8 commits into from
Mar 29, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions .php_cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@
$header = <<<'EOF'
This file is part of Swoft.

@link https://swoft.org
@link https://swoft.org
@document https://doc.swoft.org
@contact [email protected]
@license https://github.com/swoft-cloud/swoft/blob/master/LICENSE
@contact [email protected]
@license https://github.com/swoft-cloud/swoft/blob/master/LICENSE
EOF;

return PhpCsFixer\Config::create()
->setRiskyAllowed(true)
->setRules([
'@PSR2' => true,
'header_comment' => [
'commentType' => 'PHPDoc',
'header' => $header,
Expand All @@ -21,6 +22,9 @@ return PhpCsFixer\Config::create()
'syntax' => 'short'
],
'single_quote' => true,
'class_attributes_separation' => true,
'no_unused_imports' => true,
'standardize_not_equals' => true,
])
->setFinder(
PhpCsFixer\Finder::create()
Expand Down
35 changes: 27 additions & 8 deletions src/Aop/Aop.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
<?php
/**
* This file is part of Swoft.
*
* @link https://swoft.org
* @document https://doc.swoft.org
* @contact [email protected]
* @license https://github.com/swoft-cloud/swoft/blob/master/LICENSE
*/

namespace Swoft\Aop;

use Swoft\Bean\Annotation\Bean;
use Swoft\Bean\Collector\AspectCollector;
use \Throwable;

/**
* @Bean()
Expand Down Expand Up @@ -57,7 +66,7 @@ public function execute($target, string $method, array $params)
* @param array $params The parameters of execution method
* @param array $advices The advices of this object method
* @return mixed
* @throws \ReflectionException
* @throws \ReflectionException|Throwable
*/
public function doAdvice($target, string $method, array $params, array $advices)
{
Expand All @@ -75,7 +84,7 @@ public function doAdvice($target, string $method, array $params, array $advices)
// The result of before point will not effect origin object method
$this->doPoint($advice['before'], $target, $method, $params, $advice, $advices);
}
if(0 === count($advices)) {
if (0 === \count($advices)) {
$result = $target->$method(...$params);
} else {
$this->doAdvice($target, $method, $params, $advices);
Expand All @@ -86,9 +95,11 @@ public function doAdvice($target, string $method, array $params, array $advices)
if (isset($advice['after']) && ! empty($advice['after'])) {
$this->doPoint($advice['after'], $target, $method, $params, $advice, $advices, $result);
}
} catch (\Exception $e) {
} catch (Throwable $t) {
if (isset($advice['afterThrowing']) && ! empty($advice['afterThrowing'])) {
return $this->doPoint($advice['afterThrowing'], $target, $method, $params, $advice, $advices);
return $this->doPoint($advice['afterThrowing'], $target, $method, $params, $advice, $advices, null, $t);
} else {
throw $t;
}
}

Expand All @@ -110,6 +121,7 @@ public function doAdvice($target, string $method, array $params, array $advices)
* @param array $advice the advice of pointcut
* @param array $advices The advices of this object method
* @param mixed $return
* @param Throwable $catch The Throwable object caught
* @return mixed
* @throws \ReflectionException
*/
Expand All @@ -120,7 +132,8 @@ private function doPoint(
array $args,
array $advice,
array $advices,
$return = null
$return = null,
Throwable $catch = null
) {
list($aspectClass, $aspectMethod) = $pointAdvice;

Expand All @@ -140,13 +153,19 @@ private function doPoint(
// JoinPoint object
$type = $parameterType->__toString();
if ($type === JoinPoint::class) {
$aspectArgs[] = new JoinPoint($target, $method, $args, $return);
$aspectArgs[] = new JoinPoint($target, $method, $args, $return, $catch);
continue;
}

// ProceedingJoinPoint object
if ($type === ProceedingJoinPoint::class) {
$aspectArgs[] = new ProceedingJoinPoint($target, $method, $args, $advice, $advices, $return);
$aspectArgs[] = new ProceedingJoinPoint($target, $method, $args, $advice, $advices);
continue;
}

//Throwable object
if (isset($catch) && $catch instanceof $type) {
$aspectArgs[] = $catch;
continue;
}
$aspectArgs[] = null;
Expand Down Expand Up @@ -243,7 +262,7 @@ private function matchExecution(string $class, string $method, array $executions
}

// Method
$reg = '/^' . $executionMethod . '$/';
$reg = '/^(?:' . $executionMethod . ')$/';
if (preg_match($reg, $method)) {
return true;
}
Expand Down
27 changes: 26 additions & 1 deletion src/Aop/JoinPoint.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
<?php
/**
* This file is part of Swoft.
*
* @link https://swoft.org
* @document https://doc.swoft.org
* @contact [email protected]
* @license https://github.com/swoft-cloud/swoft/blob/master/LICENSE
*/

namespace Swoft\Aop;

use \Throwable;

/**
* the join point of class
*
Expand Down Expand Up @@ -33,20 +43,27 @@ class JoinPoint implements JoinPointInterface
*/
protected $method;

/**
* @var Throwable
*/
protected $catch;

/**
* JoinPoint constructor.
*
* @param object $target the object of origin
* @param string $method the method of origin
* @param array $args the params of method
* @param mixed $return the return of executed method
* @param Throwable $catch the throwable caught of the origin
*/
public function __construct($target, string $method, array $args, $return = null)
public function __construct($target, string $method, array $args, $return = null, $catch = null)
{
$this->args = $args;
$this->return = $return;
$this->target = $target;
$this->method = $method;
$this->catch = $catch;
}

/**
Expand Down Expand Up @@ -80,4 +97,12 @@ public function getMethod(): string
{
return $this->method;
}

/**
* @return null|Throwable
*/
public function getCatch()
{
return $this->catch;
}
}
24 changes: 16 additions & 8 deletions test/Cases/Aop/AllPointAspectWithoutRound1.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,17 @@
/**
* This file is part of Swoft.
*
* @link https://swoft.org
* @link https://swoft.org
* @document https://doc.swoft.org
* @contact [email protected]
* @license https://github.com/swoft-cloud/swoft/blob/master/LICENSE
* @contact [email protected]
* @license https://github.com/swoft-cloud/swoft/blob/master/LICENSE
*/
namespace SwoftTest\Aop;

use Swoft\Aop\JoinPoint;
use Swoft\Aop\ProceedingJoinPoint;
use Swoft\Bean\Annotation\After;
use Swoft\Bean\Annotation\AfterReturning;
use Swoft\Bean\Annotation\AfterThrowing;
use Swoft\Bean\Annotation\Around;
use Swoft\Bean\Annotation\Aspect;
use Swoft\Bean\Annotation\Before;
use Swoft\Bean\Annotation\PointBean;
Expand All @@ -35,7 +33,10 @@
*/
class AllPointAspectWithoutRound1
{

/**
* @var \Throwable
*/
public static $catch;

/**
* @Before()
Expand All @@ -61,6 +62,13 @@ public function afterReturn()
echo ' afterReturn1withoutaround ';
}



/**
* @param JoinPoint $joinPoint
* @throws
* @AfterThrowing
*/
public function afterThrowing(JoinPoint $joinPoint)
{
static::$catch=$joinPoint->getCatch();
}
}
27 changes: 19 additions & 8 deletions test/Cases/Aop/AllPointAspectWithoutRound2.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,16 @@
/**
* This file is part of Swoft.
*
* @link https://swoft.org
* @link https://swoft.org
* @document https://doc.swoft.org
* @contact [email protected]
* @license https://github.com/swoft-cloud/swoft/blob/master/LICENSE
* @contact [email protected]
* @license https://github.com/swoft-cloud/swoft/blob/master/LICENSE
*/
namespace SwoftTest\Aop;

use Swoft\Aop\JoinPoint;
use Swoft\Aop\ProceedingJoinPoint;
use Swoft\Bean\Annotation\After;
use Swoft\Bean\Annotation\AfterReturning;
use Swoft\Bean\Annotation\AfterThrowing;
use Swoft\Bean\Annotation\Around;
use Swoft\Bean\Annotation\Aspect;
use Swoft\Bean\Annotation\Before;
use Swoft\Bean\Annotation\PointBean;
Expand All @@ -34,6 +31,11 @@
*/
class AllPointAspectWithoutRound2
{
/**
* @var \Exception
*/
public static $catch;

/**
* @Before()
*/
Expand All @@ -58,5 +60,14 @@ public function afterReturn()
echo ' afterReturn2withoutaround ';
}


}
/**
* @param \Exception $e
* @AfterThrowing
* @throws
*/
public function afterThrowing(\Exception $e=null)
{
static::$catch=$e;
throw $e;
}
}
10 changes: 7 additions & 3 deletions test/Cases/Aop/AopBean2.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
/**
* This file is part of Swoft.
*
* @link https://swoft.org
* @link https://swoft.org
* @document https://doc.swoft.org
* @contact [email protected]
* @license https://github.com/swoft-cloud/swoft/blob/master/LICENSE
* @contact [email protected]
* @license https://github.com/swoft-cloud/swoft/blob/master/LICENSE
*/
namespace SwoftTest\Aop;

Expand All @@ -27,4 +27,8 @@ public function doAop()
echo 'do aop';
}

public function throwSth(\Throwable $t)
{
throw $t;
}
}
45 changes: 41 additions & 4 deletions test/Cases/AopTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@
/**
* This file is part of Swoft.
*
* @link https://swoft.org
* @link https://swoft.org
* @document https://doc.swoft.org
* @contact [email protected]
* @license https://github.com/swoft-cloud/swoft/blob/master/LICENSE
* @contact [email protected]
* @license https://github.com/swoft-cloud/swoft/blob/master/LICENSE
*/
namespace SwoftTest;

use Swoft\App;
use SwoftTest\Aop\AllPointAspectWithoutRound1;
use SwoftTest\Aop\AllPointAspectWithoutRound2;
use SwoftTest\Aop\AnnotationAop;
use SwoftTest\Aop\AopBean;
use SwoftTest\Aop\AopBean2;
Expand All @@ -34,7 +36,6 @@ public function testAllAdvice()
$this->assertEquals('do aop around-before2 before2 around-after2 afterReturn2 around-before1 before1 around-after1 afterReturn1 ', $result);
}


/**
* 验证问题:当切面不包含Around型通知时,不支持多层切面
* @author Jiankang [email protected]
Expand Down Expand Up @@ -81,4 +82,40 @@ public function testNewAopParams()
$result = $annotationBean->methodParams('a', 'b');
$this->assertEquals('methodParams-a-new-b-new regAspect around before regAspect around after ', $result);
}

/**
* 测试AfterThrowing切面 能否从JoinPoint获取异常
* @author Jiankang [email protected]
*/
public function testThrowableInjectByJoinPoint()
{
/* @var \SwoftTest\Aop\AopBean2 $aopBean*/
$aopBean = App::getBean(AopBean2::class);
AllPointAspectWithoutRound1::$catch=null;
$exception=new \LogicException('Bomb!');
ob_start();

$aopBean->throwSth($exception);

ob_end_clean();
$this->assertEquals($exception, AllPointAspectWithoutRound1::$catch);
}

/**
* 测试AfterThrowing切面 能否直接注入异常
* @author Jiankang [email protected]
*/
public function testThrowableInject()
{
/* @var \SwoftTest\Aop\AopBean2 $aopBean*/
$aopBean = App::getBean(AopBean2::class);
AllPointAspectWithoutRound2::$catch=null;
$exception=new \LogicException('Bomb!');
ob_start();

$aopBean->throwSth($exception);

ob_end_clean();
$this->assertEquals($exception, AllPointAspectWithoutRound2::$catch);
}
}