symfony 4.4+自动发现仅扫描app命名空间下类,bundle内服务需手动注册;触发条件为:services.yaml中_defaults启用autowire和autoconfigure、类属app命名空间、符合psr-4自动加载且未被exclude排除。

默认开启,但只扫描 App 命名空间下的类;Bundle 内服务不会被自动发现,必须手动注册。
自动发现的触发条件是什么
Symfony 4.4+ 默认启用自动发现,前提是满足以下全部条件:
-
services.yaml中_defaults下启用了autowire: true和autoconfigure: true - 类位于
App命名空间下(如src/Controller/、src/Service/) - 类文件路径符合 PSR-4 自动加载规则(
composer.json中已声明"App\": "src/") - 类没有被
exclude规则排除(如resources:下配置了!**/*Test.php是正常的,但误写!src/**就会全禁)
Bundle 里的服务为什么没被发现
Bundle 目录(如 src/MyPlugin/Bundle/)不在默认扫描路径内,autoconfigure 和 autowire 对它完全无效。常见错误现象是:bin/console debug:container | grep myservice 查不到,控制器里类型提示直接报 Target class [MyPluginBundleServiceApiClient] does not exist。
- 必须显式注册:在 Bundle 的
DependencyInjection/MyPluginExtension.php的load()方法中调用$container->register() - 或使用
Resources/config/services.yaml(Symfony 4.4+ 支持),但需在load()中通过$container->loadFromExtension()加载该文件 - 不能指望
App下的配置文件去覆盖 Bundle 内部类——命名空间不匹配,容器根本不会看
怎么验证自动发现是否生效
别只信配置,要看实际注册结果:
- 运行
bin/console debug:container --show-private | grep YourServiceClass,有输出才说明进容器了 - 如果类名带
Interface(如MailerInterface),要加--show-hidden才能看到别名绑定 - 报
Class not found?先检查composer dump-autoload是否执行过,再确认composer.json的autoload.psr-4是否包含对应命名空间 - 用
bin/console debug:container --parameters看环境变量是否已解析(比如%env(API_KEY)%没展开,服务构造就会失败)
最易被忽略的是:自动发现只解决“注册”,不解决“可用”。即使类进了容器,若构造函数依赖未定义的服务(比如写了 public function __construct(LoggerInterface $logger) 但没装 symfony/logger),容器构建阶段就会报错,且错误堆栈极深——建议先确保依赖包已安装,再查服务注册逻辑。











