@inject不生效的根本原因只有两个:类未被容器扫描到或代理类生成失败。需检查scan.php路径配置、命名空间与物理路径一致性、类是否具体可实例化,并验证代理类是否生成及是否含正确注入逻辑。

Hyperf中@Inject注解不生效的常见原因
根本原因通常只有两个:类没被容器扫描到,或者代理类生成失败导致依赖无法注入。Hyperf 的 @Inject 依赖注入完全基于 AOP 代理和注解扫描,缺一不可。
检查类是否在 @Scan 扫描路径内
Hyperf 默认只扫描 app/ 目录下的类,如果你把需要注入的类(比如 Service)放在 library/、common/ 或自定义目录下,@Inject 就不会生效 —— 因为注解压根没被解析。
- 确认你的类所在路径是否在
config/autoload/scan.php的paths数组中,例如:'paths' => [<br> BASE_PATH . '/app',<br> BASE_PATH . '/common', // 若 Service 在 common/ 下,必须加这一行<br>],
- 类必须有命名空间,且命名空间路径需与物理路径一致;否则即使路径在
scan.php中,也会因 PSR-4 解析失败而跳过 - 类不能是
abstract或interface,@Inject只支持对具体可实例化的类生效
验证代理类是否正常生成
Hyperf 在启动时会为带 @Inject 的类生成代理类(如 App\Service\UserService$$Proxy),若生成失败,注入就静默失效 —— 不报错,但属性值为 null。
- 运行
php bin/hyperf.php di:proxy,观察输出是否有类似Generate proxy for App\Service\UserService的日志;若没有,说明该类未被识别为可代理目标 - 检查类是否被
@Aspect、@Controller、@Service等注解标记(任一即可),否则默认不触发代理生成 - 代理类生成后会存于
runtime/container/proxy/,可直接查看对应.php文件是否存在、内容是否含parent::__construct()和$this->property = $container->get(...)逻辑 - 开发环境建议开启
SWOOLE_HOOK_ALL并禁用 opcache(opcache.enable=0),避免代理类加载失败
其他容易忽略的细节
有些问题看似是 @Inject 失效,实则是使用姿势或生命周期问题。
- 构造函数里访问
@Inject属性会得到null—— 因为属性注入发生在构造函数执行之后,应改用__construct参数注入或@PostConstruct回调 - 手动 new 出来的对象(如
new UserService())不会被容器管理,@Inject完全无效;必须通过$container->get(UserService::class)获取 - 如果类同时用了
@Inject和__construct参数注入,Hyperf 默认优先走构造函数注入,此时属性注入会被跳过 - 检查是否误用了
@Value或@Config注解拼写错误,导致 IDE 或扫描器误判整个类注解结构异常











