1. 什么是AOP
AOP(Aspect-oriented programming)即 面向切面的程序设计,AOP 和 OOP(Object-oriented programming)面向对象程序设计一样都是一种程序设计思想,AOP 只是 OOP 的补充和延伸,可以更方便的对业务代码进行解耦,从而提高代码质量和增加代码的可重用性。后面的篇章会结合实际案例,教会大家理解并学会使用 AOP。
2. 调用场景
- 需要记录某个接口请求的日志(接收参数,返回参数,执行时间等)
- 调用出现异常时,触发相关操作处理(发送邮件通知等等)
- 调用方法前进行权限校验等等
优点就是,在不改变原有方法代码的情况下实现你想要实现的额外功能.
3. 案例
我们那swof代码中的首页代码来示范
*/
public function index(): Response
{
/** @var Renderer $renderer */
$renderer = Swoft::getBean('view');
$content = $renderer->render('home/index');
$end_time = microtime(true);
return context()->getResponse()->withContentType(ContentType::HTML)->withContent($content);
}
当我们想对上边的代码加一个运行时间是,按照之前的写法,我们可能会写成这样:
/**
* @RequestMapping("/")
* @throws Throwable
*/
public function index(): Response
{
$begin_time = microtime(true); // 获取一个毫秒时间
/** @var Renderer $renderer */
$renderer = Swoft::getBean('view');
$content = $renderer->render('home/index');
$end_time = microtime(true); // 在获取一个毫秒时间
vdump("运行时间为:", round(($end_time - $begin_time) * 1000, 3)); // 拿开始时间减去结束时间 乘以1000 得到一个描述,在保留3位小数
return context()->getResponse()->withContentType(ContentType::HTML)->withContent($content);
}
运行结果是这样的:(在控制台中查看结果)
PRINT ON App\Http\Controller\HomeController(41):
string(16) "运行时间为:"
float(2.058)
这样有个缺点就是,只是计算了当前$bengin_time
与$end_time
之间代码的运算时间,并且我们修改了原方法,那么我们如何才能不通过修改源代码的方式,也能得到运算时间呢?
我们首先先顶一个切面类,类似于这样:
<?php declare(strict_types=1);
namespace App\Aspect;
use App\Http\Controller\HomeController;
use Swoft\Aop\Annotation\Mapping\After;
use Swoft\Aop\Annotation\Mapping\Aspect;
use Swoft\Aop\Annotation\Mapping\Before;
use Swoft\Aop\Annotation\Mapping\PointBean;
use Swoft\Aop\Point\JoinPoint;
/**
* @Aspect(order=1) # 优先级, 数字越小则优先执行。
*
* @PointBean(include={HomeController::class}) # 这里指的是定义切入目标。注意需要use引入一下这个类
*/
class YingxiaozhuAspect {
/** @var float 执行开始 */
private $time_begin;
/**
* 前置通知
*
* @Before()
*/
public function beforeAdvice()
{
// 起点时间
$this->time_begin = microtime(true);
}
/**
* 后置通知
*
* @After()
*
* @param JoinPoint $joinPoint
*/
public function afterAdvice(JoinPoint $joinPoint)
{
/** @var float 执行结束 */
$timeFinish = microtime(true);
$method = $joinPoint->getMethod();
$runtime = round(($timeFinish - $this->time_begin) * 1000, 3);
echo "{$method} 方法,本次执行时间为: {$runtime}ms \n";
}
}
重启服务,访问首页查看一下结果:
index 方法,本次执行时间为: 4.072ms
关注颖小主其他相关文章,后续带你理解AOP原理
,前置通知
、后置通知
、返回通知
、异常通知
、环绕通知