自定义进程类需加@process(callback: true)并用构造函数注入,否则@inject无效;还需执行di:dump和di:proxy:generate生成代理文件。

自定义进程类没被容器创建,@Inject自然不工作
Hyperf 的 @Inject 注解只在容器管理的对象上生效。而自定义进程(AbstractProcess 子类)默认由框架用 new 直接实例化,跳过 DI 容器——所以即使你写了 #[Inject],属性永远是 null。
这不是注解写错了,也不是扫描漏了,而是生命周期层面的机制限制:进程启动时,Hyperf 尚未完成容器初始化,或根本没走容器获取流程。
- 检查你的进程类是否加了
@Process注解(必须有,否则不会被识别为可托管进程) - 确认该类路径已加入
config/autoload/scan.php的paths数组(比如BASE_PATH . '/app/Process') - 确保类不是
abstract,且命名空间与物理路径严格一致(PSR-4 必须匹配)
正确做法:用构造函数参数 + #[Inject] 显式声明依赖
属性注入在自定义进程中完全不可靠,唯一稳定的方式是把依赖声明在构造函数里,并用 #[Inject] 标注参数。但前提是:这个类必须由容器来 new,而不是框架手动 new。
本页面提供企业级 PHP 协程框架 Hyperf 3.1.66 版本的官方源码下载与完整更新日志。重点解析 v3.1.66 版本中新增的 gRPC 多客户端负载均衡支持、Pool 连接池全量刷新、Guzzle 持久化 Cookie 以及数据库 JSON 包含键查询等核心优化特性。
Hyperf 2.2+ 支持通过 @Process 注解的 callback 属性交由容器接管实例化过程:
#[Process(callback: true)]
class MyProcess extends AbstractProcess
{
public function __construct(#[Inject] UserService $userService)
{
$this->userService = $userService;
}
}
-
callback: true是关键,它告诉 Hyperf:别手动 new,改用$container->get(MyProcess::class) - 此时构造函数参数才能被容器解析,
#[Inject]才真正起作用 - 如果没加
callback: true,哪怕构造函数写了#[Inject],也还是null
运行前必须执行 di:dump 和 di:proxy:generate
即使配置全对,代理类没生成或容器定义过期,@Inject 依然静默失效。自定义进程类属于 AOP 代理目标,必须生成对应 $$Proxy 文件。
- 先清缓存:
php bin/hyperf.php di:clear - 再生成容器定义:
php bin/hyperf.php di:dump - 最后强制生成代理:
php bin/hyperf.php di:proxy:generate - 检查
runtime/container/proxy/下是否有类似MyProcess$$Proxy.php的文件,内容应含$this->userService = $container->get(UserService::class)
容易忽略的陷阱:进程启动时机早于容器就绪
有些场景下,进程在 onStart 阶段就尝试访问注入属性,但此时容器可能还没完成所有绑定(尤其是动态注册的 singleton())。结果就是:构造函数能拿到实例,但 process() 里一调方法就报错。
- 不要在
onStart或onWorkerStart中直接使用注入对象,除非你确认它们已在register()阶段完成绑定 - 避免在进程类中用
ApplicationContext::getContainer()->get()手动取依赖——这绕过了构造函数注入逻辑,容易引发重复实例化或状态混乱 - 如果依赖本身是闭包绑定(
bind()),务必改用singleton(),否则get()返回的是Closure而非实例










