Symfony调用服务的触发条件是什么?API Platform升级装饰器失效
解答
1. Symfony服务缓存生成与服务调用的触发条件
首先你对文件加载的猜测不完全准确:Symfony不会默认加载src目录下所有PHP文件,你看到的JwtDecorator类被加载,是容器缓存 freshness 校验阶段需要反射该类计算哈希,判断类文件是否有改动,仅针对已经在服务配置中注册的类才会触发该加载逻辑。
服务缓存生成触发条件
- dev环境默认开启
auto_reload配置,每次请求都会先校验现有容器缓存是否有效:所有关联的配置文件、服务类、参数等资源的哈希/修改时间和缓存中记录的一致则判定为新鲜,否则触发重新编译 - 缓存不存在(首次运行、手动清空
var/cache目录)时也会触发编译 - 编译阶段会解析所有服务配置,处理装饰器、别名、标签等规则,为每个有效服务生成对应的
getXXXService懒加载类,写入缓存目录
服务调用触发条件
- 只有当服务被实际依赖时才会触发实例化:比如被其他服务构造函数注入、控制器主动依赖、直接从容器中get该服务,此时才会执行对应
getXXXService中的代码,调用服务构造函数 - 你2.7版本没有生成对应装饰器的服务缓存类,说明容器编译阶段直接判定该装饰器无效,没有纳入服务列表
2. 版本差异排查方法与根因定位
排查步骤
- 首先校验OpenApi相关的命名空间与服务id变更:
API Platform 2.7是向3.0过渡的版本,已经把原来ApiPlatform\Core下的OpenApi相关类迁移到了顶层命名空间:
原接口ApiPlatform\Core\OpenApi\Factory\OpenApiFactoryInterface替换为ApiPlatform\OpenApi\Factory\OpenApiFactoryInterface,你的JwtDecorator实现的是旧版接口,编译阶段会因为接口不匹配,被判定为无效的装饰器直接忽略,不会生成服务缓存。 - 可以执行以下命令确认当前版本的装饰目标是否存在:
php bin/console debug:container api_platform.openapi.factory查看该服务的对应实现类、接口是否匹配你装饰器注入的类型 - 执行
php bin/console debug:container --decorations api_platform.openapi.factory对比两个版本的装饰器列表,看2.7版本是否存在你的JwtDecorator
修复方案
把JwtDecorator中的相关import替换为2.7版本的新命名空间,清空缓存后即可恢复生效:
use ApiPlatform\OpenApi\Factory\OpenApiFactoryInterface; use ApiPlatform\OpenApi\OpenApi; use ApiPlatform\OpenApi\Model;
内容的提问来源于stack exchange,提问作者user1032531
相关产品推荐
相关产品推荐

