Symfony 6:如何用注解为接口指定默认实现并装饰?
用注解定义接口服务别名并实现生产环境装饰
1. 给默认实现添加接口别名注解
针对FilterMetadataFactory这个唯一实现,通过@AsAlias注解将它与FilterMetadataFactoryInterface绑定,让容器能通过接口类名引用该服务:
use Symfony\Component\DependencyInjection\Attribute\AsAlias; use Symfony\Component\DependencyInjection\Attribute\Autoconfigure; #[Autoconfigure] #[AsAlias(alias: FilterMetadataFactoryInterface::class, public: false)] class FilterMetadataFactory implements FilterMetadataFactoryInterface { // 你的接口实现代码 }
alias参数填入目标接口的完整类名public设为false表示该别名仅容器内部可用,无需暴露给外部
2. 多实现场景下的别名优先级控制
如果后续有多个类实现FilterMetadataFactoryInterface,可以通过priority参数指定哪个实现成为接口别名的默认指向:
#[Autoconfigure] #[AsAlias(alias: FilterMetadataFactoryInterface::class, priority: 20, public: false)] class AlternativeFilterMetadataFactory implements FilterMetadataFactoryInterface { // 另一种实现逻辑 }
优先级数值越大,越会被优先选为接口别名对应的服务(默认优先级为0)。
3. 生产环境专属的装饰器配置
要让CachedFilterMetadataFactory仅在生产环境装饰默认服务,结合@When和@Decorate注解即可:
use Symfony\Component\DependencyInjection\Attribute\Decorate; use Symfony\Component\DependencyInjection\Attribute\When; #[When(env: 'prod')] #[Decorate(decorates: FilterMetadataFactoryInterface::class)] class CachedFilterMetadataFactory implements FilterMetadataFactoryInterface { public function __construct(private FilterMetadataFactoryInterface $innerService) { // 被装饰的原始服务会自动注入到构造方法 } public function getMetadata(string $filter): FilterMetadata { // 这里添加你的缓存逻辑 return $this->innerService->getMetadata($filter); } }
#[When(env: 'prod')]确保该服务仅在生产环境被加载#[Decorate]指定要装饰的目标服务(即我们定义的接口别名),Symfony会自动处理装饰器的服务链逻辑
内容的提问来源于stack exchange,提问作者gremo
相关产品推荐
相关产品推荐

