feat : Decorator Aop

This commit is contained in:
2025-09-06 23:53:15 +08:00
parent aaa394a2a7
commit dfbb4b73ae
9 changed files with 195 additions and 9 deletions

View File

@@ -2,11 +2,13 @@
namespace App\Aspect; namespace App\Aspect;
use App\Interface\Test\Decorator\LoggerInterface;
use App\Lib\Return\AdminReturn; use App\Lib\Return\AdminReturn;
use App\Lib\Return\CommonReturn; use App\Lib\Return\CommonReturn;
use App\Lib\Return\TestReturn; use App\Lib\Return\TestReturn;
use Hyperf\Context\Context; use Hyperf\Context\Context;
use Hyperf\Di\Annotation\Aspect; use Hyperf\Di\Annotation\Aspect;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Di\Aop\AbstractAspect; use Hyperf\Di\Aop\AbstractAspect;
use Hyperf\Di\Aop\ProceedingJoinPoint; use Hyperf\Di\Aop\ProceedingJoinPoint;
use Hyperf\Di\Exception\Exception; use Hyperf\Di\Exception\Exception;
@@ -31,6 +33,12 @@ class CommonReturnAspect extends AbstractAspect
*/ */
public array $annotations = []; public array $annotations = [];
/**
* @var LoggerInterface
*/
#[Inject]
protected LoggerInterface $logger;
/** /**
* 依赖注入容器 * 依赖注入容器
* @param RequestInterface $request * @param RequestInterface $request
@@ -49,8 +57,6 @@ class CommonReturnAspect extends AbstractAspect
*/ */
public function process(ProceedingJoinPoint $proceedingJoinPoint): mixed public function process(ProceedingJoinPoint $proceedingJoinPoint): mixed
{ {
echo 1;
var_dump(1);
// 在调用前进行处理 // 在调用前进行处理
$result = $proceedingJoinPoint->process(); $result = $proceedingJoinPoint->process();
// 在调用后进行处理 // 在调用后进行处理
@@ -70,8 +76,8 @@ class CommonReturnAspect extends AbstractAspect
*/ */
private function writeResponseLog(string $content): void private function writeResponseLog(string $content): void
{ {
echo json_encode($this->request->all()); $this->logger->log('返回切入请求体:'.json_encode($this->request->all()));
echo $this->userId; $this->logger->log('返回切入用户id:'.$this->userId);
echo json_encode($content); $this->logger->log('返回切入返回体:'.$content);
} }
} }

View File

@@ -0,0 +1,54 @@
<?php
namespace App\Aspect\Test\Decorator\Aop;
use App\Service\Test\Decorator\Aop\UserService;
use Hyperf\Cache\Cache;
use Hyperf\Context\ApplicationContext;
use Hyperf\Di\Annotation\Aspect;
use Hyperf\Di\Aop\AbstractAspect;
use Hyperf\Di\Aop\ProceedingJoinPoint;
use Hyperf\Di\Exception\Exception;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\SimpleCache\InvalidArgumentException;
/**
* 切入类 属性值 priority 数字越大优先级越高 提前返回的CacheableAspect类必须要在后面
*/
#[Aspect(priority: 1)]
class CacheableAspect extends AbstractAspect
{
/**
* 切入接口类
* @var array|string[]
*/
public array $classes = [
UserService::class . '::getUserInfo',
];
/**
* @param ProceedingJoinPoint $proceedingJoinPoint
* @return mixed
* @throws Exception
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws InvalidArgumentException
*/
public function process(ProceedingJoinPoint $proceedingJoinPoint): mixed
{
$userId = $proceedingJoinPoint->arguments['keys']['userId'];
print_r('切入cache数据:'.json_encode($proceedingJoinPoint->arguments));
$cacheKey = 'list:userInfo:' . $userId;
$cache = ApplicationContext::getContainer()->get(Cache::class);
if ($cache->has($cacheKey)) return $cache->get($cacheKey);
$result = $proceedingJoinPoint->process();
$cache->set($cacheKey, $result, 3600);
return $result;
}
}

View File

@@ -0,0 +1,49 @@
<?php
namespace App\Aspect\Test\Decorator\Aop;
use App\Interface\Test\Decorator\LoggerInterface;
use App\Service\Test\Decorator\Aop\UserService;
use Hyperf\Di\Annotation\Aspect;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Di\Aop\AbstractAspect;
use Hyperf\Di\Aop\ProceedingJoinPoint;
use Hyperf\Di\Exception\Exception;
#[Aspect(priority: 2)]
class LoggableAspect extends AbstractAspect
{
/**
* 切入接口类
* @var array|string[]
*/
public array $classes = [
UserService::class . '::getUserInfo',
];
/**
* @var LoggerInterface
*/
#[Inject]
protected LoggerInterface $logger;
/**
* @param ProceedingJoinPoint $proceedingJoinPoint
* @return mixed
* @throws Exception
*/
public function process(ProceedingJoinPoint $proceedingJoinPoint): mixed
{
$userId = $proceedingJoinPoint->arguments['keys']['userId'];
// $logger = ApplicationContext::getContainer()->get(LoggerFactory::class)->get('app');
print_r('切入logger数据:'.json_encode($proceedingJoinPoint->arguments));
$this->logger->debug('调用前获取用户信息的ID' . $userId);
$result = $proceedingJoinPoint->process();
$this->logger->debug('调用后检索用户信息的ID' . $userId);
return $result;
}
}

View File

@@ -26,6 +26,7 @@ class DecoratorController extends AbstractController
} }
/** /**
* container 装饰器(依赖注入)
* @return array * @return array
*/ */
#[RequestMapping(path: 'container', methods: 'GET')] #[RequestMapping(path: 'container', methods: 'GET')]
@@ -34,7 +35,12 @@ class DecoratorController extends AbstractController
return (new ContainerService)->handle(); return (new ContainerService)->handle();
} }
public function aop() /**
* aop 装饰器(切面)
* @return array
*/
#[RequestMapping(path: 'aop', methods: 'GET')]
public function aop(): array
{ {
return (new AopService)->handle(); return (new AopService)->handle();
} }

View File

@@ -0,0 +1,13 @@
<?php
namespace App\Interface\Test\Decorator;
interface UserServiceInterface
{
/**
* 获取用户信息的接口
* @param int $userId
* @return array
*/
public function getUserInfo(int $userId): array;
}

View File

@@ -0,0 +1,31 @@
<?php
/**
* This service file is part of item.
*
* @author ctexthuang
* @contact ctexthuang@qq.com
* @web_site https://ctexthuang.com
*/
declare(strict_types=1);
namespace App\Service\Test\Decorator\Aop;
use App\Interface\Test\Decorator\UserServiceInterface;
class UserService implements UserServiceInterface
{
/**
* @param int $userId
* @return array
*/
public function getUserInfo(int $userId): array
{
// 模拟数据库查询
return [
'id' => $userId,
'name' => 'User ' . $userId,
'email' => 'user' . $userId . '@ctexthuang.com'
];
}
}

View File

@@ -11,12 +11,25 @@ declare(strict_types=1);
namespace App\Service\Test\Decorator; namespace App\Service\Test\Decorator;
use App\Service\Test\Decorator\Aop\UserService;
use App\Service\Test\TestBaseService; use App\Service\Test\TestBaseService;
use Hyperf\Di\Annotation\Inject;
class AopService extends TestBaseService class AopService extends TestBaseService
{ {
public function handle() /**
* @var UserService
*/
#[Inject]
protected UserService $userService;
/**
* @return array
*/
public function handle(): array
{ {
return $this->return->success(); $userInfo = $this->userService->getUserInfo($this->request->input('user_id',1));
return $this->return->success('获取用户信息成功', $userInfo);
} }
} }

View File

@@ -5,6 +5,7 @@ namespace App\Service\Test;
use App\Lib\Return\TestReturn; use App\Lib\Return\TestReturn;
use App\Service\BaseService; use App\Service\BaseService;
use Hyperf\Di\Annotation\Inject; use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Contract\RequestInterface;
abstract class TestBaseService extends BaseService abstract class TestBaseService extends BaseService
{ {
@@ -14,5 +15,11 @@ abstract class TestBaseService extends BaseService
#[Inject] #[Inject]
protected TestReturn $return; protected TestReturn $return;
/**
* @var RequestInterface
*/
#[Inject]
protected RequestInterface $request;
abstract public function handle(); abstract public function handle();
} }

View File

@@ -21,3 +21,10 @@ Content-Type: application/x-www-form-urlencoded
### Decorator container test ### Decorator container test
GET {{host}}/decorator/test/container GET {{host}}/decorator/test/container
Content-Type: application/x-www-form-urlencoded Content-Type: application/x-www-form-urlencoded
### Decorator aop test
GET {{host}}/decorator/test/aop
Content-Type: application/x-www-form-urlencoded
user_id=12