切面类未出现在di:dump输出中,说明未被扫描到:需确认config/autoload/annotations.php中scan.scan_dirs包含切面目录(如app\aspect),切面类带#[aspect]注解且非abstract/final,未被scan.ignore_annotations忽略,php 8+下属性类型提示不触发扫描。

切面类没出现在 di:dump 输出里,说明根本没被扫描到
Hyperf 的 AOP 不是“写了就生效”,它依赖注解扫描器发现带 #[Aspect] 的类。如果 php bin/hyperf.php di:dump 搜索不到你的切面全名(比如 App\Aspect\TraceAspect),那后续所有排查都是徒劳。
检查点:
-
config/autoload/annotations.php中scan.scan_dirs是否包含切面所在目录(如App\Aspect);漏写、拼错命名空间或路径分隔符(Windows 下反斜杠未转义)都会跳过 - 切面类必须有 #[Aspect] 注解(不是 @Aspect),且不能是
abstract或final - 别信 IDE 补全:PHP 8.0+ 属性类型提示(如
public TraceAspect $aspect;)不会触发扫描,必须加 #[Inject] 或其他 DI 注解才能被识别为可注入目标 -
scan.ignore_annotations配置里是否误加了Aspect—— 这会导致注解直接被跳过
代理类文件没生成,runtime/container/proxy/ 是第一现场
即使切面类被扫描进容器,Hyperf 还要生成代理类并注册进 DI 容器。这一步失败,process() 就永远不会执行。
确认方式:
- 进入
runtime/container/proxy/目录,看是否有对应目标类的 PHP 文件(如App_Service_UserService.php);没有 = 代理未生成 - 执行
vendor/bin/init-proxy.sh,观察控制台是否输出Generated proxy for App\Service\UserService—— 这是唯一能确认代理真实生成的日志依据 -
php bin/hyperf.php dev:build不会生成代理类,它只编译 DI 定义,不扫描注解、不重写类、不写入 proxy 文件 - 代理类生成只发生在两个时机:
php bin/hyperf.php start启动时,或手动运行vendor/bin/init-proxy.sh
目标方法调用走的是原始类,不是代理类
常见现象:切面类在 di:dump 里有、proxy 文件也存在,但 process() 就是不进。大概率是调用路径没经过代理对象。
关键判断:
- 在切面
process()里加var_dump(get_class($proceedingJoinPoint->getClassName()));,输出是不是类似Hyperf\Di\Aop\Proxy\App_Service_UserService$$HyperfProxy?如果不是,说明调用来源不是容器返回的代理实例 - 子类里调
$this->parentMethod()是内部调用,走原始父类,不会触发 AOP;必须由外部通过 DI 获取实例后调用,且该方法需显式列在切面的$classes或$annotations中 - 父类方法想被切入,必须单独写进切面配置,例如
'App\Service\ParentService::doSomething';Hyperf 不自动递归继承链 - 抽象类、接口无法生成代理类,只能代理具体实现类
清缓存 ≠ 切面生效,三步操作缺一不可
很多人删了 runtime/container 还不生效,是因为只做了表面清理。Hyperf 的 AOP 生效依赖三个状态同步:文件系统、Composer autoloader、Swoole Worker 内存。
正确刷新顺序:
- 删除整个
runtime/container目录:rm -rf runtime/container - 确认原类已被重命名(如
app/Service/UserService.php文件头是否含class UserServiceOrigin;若无,说明代理根本没生成过,先跑vendor/bin/init-proxy.sh) - 重启服务:
php bin/hyperf.php start(开发)或php bin/hyperf.php server:restart(生产)
改完切面不重启,旧代理逻辑还在 Worker 进程里复用;删了目录但没重启,autoloader 可能还缓存着旧路径;原类没重命名,启动时会报 Class App\Service\UserServiceOrigin not found —— 这三点最容易被忽略。











