概念
AOP 为 Aspect Oriented Programming
的缩写,意为:面向切面编程
,通过动态代理等技术实现程序功能的统一维护的一种技术。AOP 是 OOP 的延续,也是 Hyperf 中的一个重要内容,是函数式编程的一种衍生范型。利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
用通俗的话来讲,就是在 Hyperf 里可以通过 切面(Aspect)
介入到任意类的任意方法的执行流程中去,从而改变或加强原方法的功能,这就是 AOP。
注意这里所指的任意类并不是完全意义上的所有类,在 Hyperf 启动初期用于实现 AOP 功能的类自身不能被切入。
介绍
相对于其它框架实现的 AOP 功能的使用方式,我们进一步简化了该功能的使用不做过细的划分,仅存在 环绕(Around)
一种通用的形式:
切面(Aspect)
为对流程织入的定义类,包括要介入的目标,以及实现对原方法的修改加强处理代理类(ProxyClass)
,每个被介入的目标类最终都会生成一个代理类,来达到执行切面(Aspect)
方法的目的
AOP的使用
示例如下,定义一个切面 /App/Aspect/TestAspect.php 切入到用户注册UserController/register 方法中,实现注册之前和注册完成后的逻辑控制:
(每个切面必须定义 @Aspect 注解或在 config/autoload/aspects.php 内进行配置)
<?php
namespace App\Aspect;
use App\Controller\UserController;
//use App\Annotation\SomeAnnotation;
use Hyperf\Di\Annotation\Aspect;
use Hyperf\Di\Aop\AbstractAspect;
use Hyperf\Di\Aop\ProceedingJoinPoint;
/**
* @Aspect
*/
class TestAspect extends AbstractAspect
{
//要切入的类或Trait或方法,可以多个
public $classes = [
//以下三种方式示例效果相同
'App\Controller\UserController::register', //切入具体某个方法
// UserController::class, //切入类
// 'App\Controller\UserController::*ter', //通过*模糊匹配
];
//要切入的注解,具体切入的还是使用了这些注解的类,仅可切入类注解和类方法注解
public $annotations = [
// SomeAnnotation::class,
];
//切面切入后执行的控制逻辑
public function process(ProceedingJoinPoint $proceedingJoinPoint)
{
//示例:调用前进行某些处理
echo date("H:i:s",time()) . ":切入注册方法\n";
//示例:调用后进行某些处理
$result = $proceedingJoinPoint->process(); //通过连接点的process()方法获得调用原方法结果
echo date("H:i:s",time()) . ":注册成功uid:". $result["uid"] . "\n";
}
}
用户注册:
<?php
declare(strict_types=1);
namespace App\Controller;
use Hyperf\HttpServer\Annotation\AutoController;
use Hyperf\Di\Annotation\Inject;
/**
* @AutoController()
*/
class UserController
{
//注册
public function register()
{
echo date("H:i:s",time()) . ":开始注册\n";
sleep(1);
echo date("H:i:s",time()) . ":完成注册\n";
//用户信息
$userInfo = ['uid' => 666, 'mobile'=> 18888888888];
return $userInfo;
}
}
调用结果如下:
切入注册方法
开始注册
完成注册
注册成功uid:666