Symfony容器为何出现服务重复?及自定义服务注册问题咨询
问题1:Symfony容器为何会存在服务重复的情况?
服务重复在Symfony里大多是因为同一个服务(或同一个类)被多次注册了,常见的场景有这么几个:
- 自动扫描与手动定义撞车:这是最常见的情况——就像你现在的配置一样,用
App\:自动扫描src目录下的类时,Symfony会自动把App\Service\SomeService这类类注册成服务(默认服务ID一般是类的全限定名,比如App\Service\SomeService,或者按命名规则转成小写的app.service.someservice),但你又手动写了一个someservice的服务指向同一个类,这就等于同一个类被注册成了两个不同ID的服务,造成重复。 - 多配置文件重复定义:如果在
services.yaml、services_dev.yaml这类不同环境的配置文件里,重复定义了同一个服务ID,或者同一个类的服务,也会出现重复。 - Bundle服务与自定义服务冲突:有些Bundle会自动注册一些服务,如果你刚好又手动注册了同一个类的服务,也会导致重复。
- 标签/别名重复配置:偶尔给同一个服务加了重复的标签,或者别名定义冲突,也可能被识别为服务重复,但这种情况相对少见。
问题2:解决
SomeService服务重复的问题 先拆解下你的services.yaml配置问题:
services: _defaults: autowire: false autoconfigure: true public: true App\: resource: '../src/*' exclude: '../src/{Entity,Migrations,Tests,Kernel.php}' App\Controller\: resource: '../src/Controller' tags: ['controller.service_arguments'] someservice: class: App\Service\SomeService
这里的核心矛盾就是:App\: 这段配置已经自动扫描并注册了App\Service\SomeService为服务,而你又手动定义了一个someservice服务指向同一个类,等于同一个类被注册了两次。
给你两个解决方案,看你需求选:
方案一:保留手动定义的someservice,关闭自动注册该类
修改App\: 的排除规则,把SomeService排除出去,这样自动扫描就不会碰这个类,只有你手动定义的服务生效:
App\: resource: '../src/*' exclude: '../src/{Entity,Migrations,Tests,Kernel.php,Service/SomeService.php}'
方案二:去掉手动定义,用自动注册的服务(推荐)
直接删掉配置里的someservice那段,Symfony已经帮你注册好了这个服务,你可以直接用类的全限定名App\Service\SomeService作为服务ID来调用它。如果还是想用someservice这个短ID,加个别名就行:
App\: resource: '../src/*' exclude: '../src/{Entity,Migrations,Tests,Kernel.php}' someservice: alias: App\Service\SomeService
另外提个小建议:你的_defaults里autowire: false,如果SomeService里有依赖需要注入的话,建议把autowire改成true,这样Symfony会自动帮你处理依赖注入,不用手动写配置,省心很多。
内容的提问来源于stack exchange,提问作者Alexey Chuhrov
相关产品推荐
相关产品推荐

