diff --git a/doc/components/aop/index.md b/doc/components/aop/index.md index c39862239b..a4270f7ce4 100644 --- a/doc/components/aop/index.md +++ b/doc/components/aop/index.md @@ -61,6 +61,12 @@ AOP 可以很好地解决这个问题,不仅可以在编写上不用事先定 普通的类,你要切入的类。 +**参数:** + +名称 | 描述 | 默认值 +-|-|- +priority | 优先级,越大越先执行 | `0` + ### 切入点 PointCut 普通类中的方法,你要切入的方法。 @@ -72,6 +78,7 @@ AOP 可以很好地解决这个问题,不仅可以在编写上不用事先定 type | 切入点类型,PointCutType::XXX | PointCutType::METHOD allow | 允许的切入点 | `[]` deny | 不允许的切入点,即使包含中有的,也可以被排除 | `[]` +priority | 优先级,越大越先执行,为 `null` 时使用 `Aspect` 设置 | `null` **切入点类型(`\Imi\Aop\PointCutType`):** @@ -252,7 +259,7 @@ return [ ] ], 'after' => [ - + ] ] ] @@ -380,15 +387,15 @@ class TestClass */ #[Inject(name: \XXX\Model\User::class)] protected $model; - + /** * 某Model对象,通过注释类型注入 - * + * * @var XXX\Model\User */ #[Inject] protected $model2; - + /** * 某Model对象,类型声明注入 */ diff --git a/src/Aop/Annotation/PointCut.php b/src/Aop/Annotation/PointCut.php index f11dae2747..57ac7e2c9b 100644 --- a/src/Aop/Annotation/PointCut.php +++ b/src/Aop/Annotation/PointCut.php @@ -25,7 +25,12 @@ public function __construct( /** * 不允许的切入点,即使包含中有的,也可以被排除. */ - public array $deny = [] + public array $deny = [], + /** + * 优先级,越大越先执行. + * 为 null 时使用 Aspect 设置. + */ + public ?int $priority = null ) { } } diff --git a/src/Aop/AopAnnotationLoader.php b/src/Aop/AopAnnotationLoader.php index f775b75912..40a808719e 100644 --- a/src/Aop/AopAnnotationLoader.php +++ b/src/Aop/AopAnnotationLoader.php @@ -77,7 +77,7 @@ public static function load(bool $force = true): void 'deny' => $pointCut->deny, 'extra' => $beforeAnnotation->toArray(), ]; - AopManager::addBefore($class, $method, $callback, $aspectAnnotation->priority, $options); + AopManager::addBefore($class, $method, $callback, $pointCut->priority ?? $aspectAnnotation->priority, $options); } if ($afterAnnotation) { @@ -85,7 +85,7 @@ public static function load(bool $force = true): void 'deny' => $pointCut->deny, 'extra' => $afterAnnotation->toArray(), ]; - AopManager::addAfter($class, $method, $callback, $aspectAnnotation->priority, $options); + AopManager::addAfter($class, $method, $callback, $pointCut->priority ?? $aspectAnnotation->priority, $options); } if ($aroundAnnotation) { @@ -93,7 +93,7 @@ public static function load(bool $force = true): void 'deny' => $pointCut->deny, 'extra' => $aroundAnnotation->toArray(), ]; - AopManager::addAround($class, $method, $callback, $aspectAnnotation->priority, $options); + AopManager::addAround($class, $method, $callback, $pointCut->priority ?? $aspectAnnotation->priority, $options); } if ($afterReturningAnnotation) { @@ -101,7 +101,7 @@ public static function load(bool $force = true): void 'deny' => $pointCut->deny, 'extra' => $afterReturningAnnotation->toArray(), ]; - AopManager::addAfterReturning($class, $method, $callback, $aspectAnnotation->priority, $options); + AopManager::addAfterReturning($class, $method, $callback, $pointCut->priority ?? $aspectAnnotation->priority, $options); } if ($afterThrowingAnnotation) { @@ -109,7 +109,7 @@ public static function load(bool $force = true): void 'deny' => $pointCut->deny, 'extra' => $afterThrowingAnnotation->toArray(), ]; - AopManager::addAfterThrowing($class, $method, $callback, $aspectAnnotation->priority, $options); + AopManager::addAfterThrowing($class, $method, $callback, $pointCut->priority ?? $aspectAnnotation->priority, $options); } } break; @@ -143,7 +143,7 @@ public static function load(bool $force = true): void 'deny' => $pointCut->deny, 'extra' => $beforeAnnotation->toArray(), ]; - AopManager::addBefore($class, $method, $callback, $aspectAnnotation->priority, $options); + AopManager::addBefore($class, $method, $callback, $pointCut->priority ?? $aspectAnnotation->priority, $options); } if ($afterAnnotation) { @@ -151,7 +151,7 @@ public static function load(bool $force = true): void 'deny' => $pointCut->deny, 'extra' => $afterAnnotation->toArray(), ]; - AopManager::addAfter($class, $method, $callback, $aspectAnnotation->priority, $options); + AopManager::addAfter($class, $method, $callback, $pointCut->priority ?? $aspectAnnotation->priority, $options); } if ($aroundAnnotation) { @@ -159,7 +159,7 @@ public static function load(bool $force = true): void 'deny' => $pointCut->deny, 'extra' => $aroundAnnotation->toArray(), ]; - AopManager::addAround($class, $method, $callback, $aspectAnnotation->priority, $options); + AopManager::addAround($class, $method, $callback, $pointCut->priority ?? $aspectAnnotation->priority, $options); } if ($afterReturningAnnotation) { @@ -167,7 +167,7 @@ public static function load(bool $force = true): void 'deny' => $pointCut->deny, 'extra' => $afterReturningAnnotation->toArray(), ]; - AopManager::addAfterReturning($class, $method, $callback, $aspectAnnotation->priority, $options); + AopManager::addAfterReturning($class, $method, $callback, $pointCut->priority ?? $aspectAnnotation->priority, $options); } if ($afterThrowingAnnotation) { @@ -175,7 +175,7 @@ public static function load(bool $force = true): void 'deny' => $pointCut->deny, 'extra' => $afterThrowingAnnotation->toArray(), ]; - AopManager::addAfterThrowing($class, $method, $callback, $aspectAnnotation->priority, $options); + AopManager::addAfterThrowing($class, $method, $callback, $pointCut->priority ?? $aspectAnnotation->priority, $options); } } } diff --git a/tests/unit/Component/Aop/Aop/PriorityAop.php b/tests/unit/Component/Aop/Aop/PriorityAop.php new file mode 100644 index 0000000000..a05601d3bf --- /dev/null +++ b/tests/unit/Component/Aop/Aop/PriorityAop.php @@ -0,0 +1,47 @@ +getArgs(); + $args[0][] = 1; + $joinPoint->proceed(); + + return 1; + } + + #[Around] + #[PointCut(allow: ['Imi\\Test\\Component\\Aop\\Classes\\TestPriorityClass::test'], priority: 500)] + public function aop2(AroundJoinPoint $joinPoint): mixed + { + $args = $joinPoint->getArgs(); + $args[0][] = 2; + $joinPoint->proceed(); + + return 2; + } + + #[Around] + #[PointCut(allow: ['Imi\\Test\\Component\\Aop\\Classes\\TestPriorityClass::test'], priority: 1500)] + public function aop3(AroundJoinPoint $joinPoint): mixed + { + $args = $joinPoint->getArgs(); + $args[0][] = 3; + $joinPoint->proceed(); + + return 3; + } +} diff --git a/tests/unit/Component/Aop/Classes/TestPriorityClass.php b/tests/unit/Component/Aop/Classes/TestPriorityClass.php new file mode 100644 index 0000000000..a2c3bf0ae3 --- /dev/null +++ b/tests/unit/Component/Aop/Classes/TestPriorityClass.php @@ -0,0 +1,15 @@ +assertNotNull($throwable); $this->assertEquals('test', $throwable->getMessage()); } + + public function testPriority(): void + { + $test = App::getBean(TestPriorityClass::class); + $list = []; + $result = $test->test($list); + $this->assertEquals(3, $result); + $this->assertEquals([3, 1, 2, 0], $list); + } }