如何按名称覆盖 Spring 服务 bean,仅使用注释
Posted
技术标签:
【中文标题】如何按名称覆盖 Spring 服务 bean,仅使用注释【英文标题】:How to overwrite Spring service beans by name, using annotations only 【发布时间】:2011-07-31 08:57:41 【问题描述】:鉴于我将 Spring bean 配置为
@Service("myService")
public class DefaultService extends MyService
还有一个使用这个 bean 的类
public class Consumer
@Autowired
@Qualifier("myService")
private MyService service;
...
我现在希望我的项目(包括前面的类)能够注入 Consumer
的另一个 MyService
实现。因此我想覆盖bean myService
@Service("myService")
public class SpecializedService implements MyService
导致Consumer
现在携带SpecializedService
的实例而不是DefaultService
。根据定义,我不能在 Spring 容器中拥有两个同名的 bean。我怎么能告诉春天,新服务的定义将覆盖旧服务?我不想修改Consumer
类。
【问题讨论】:
【参考方案1】:我知道,已经晚了。还在发。
您应该为 MyService 的不同实现使用不同的名称。
例如
@Service("mySpecializedService")
public class SpecializedService implements MyService
@Service("myService")
public class DefaultService extends MyService
在自动装配它们时(比如在控制器中),您可以使用@Qualifier 注入所需的实现,如下所述。
获取默认实现
@Autowired
@Qualifier("myService")
MyService myService;
获得专门的实现
@Autowired
@Qualifier("mySpecializedService")
MyService myService;
【讨论】:
这与 OP 的要求完全相反。 我会在一个单独的配置文件(xml 或 java)中定义新的 bean,并让它覆盖前一个,或者继续使用 Spring Profiles 或 @Conditional。 【参考方案2】:基于注解的连接发生在基于 XML 的配置之前,这意味着在 XML 中定义的 bean 将 覆盖注释完成的那些接线。 所以在 XML 中明确定义它,就像 Willie 所说的那样会完成这项工作
<bean id="myService" class="x.y.z.SpecializedService" />
Spring 建议对服务和存储库 bean 使用 XML,对 MVC bean 使用注释。它还建议 @Autowired 不扫描组件。但是通常鼓励使用注释,尽管它将代码和配置合并在一起(反对分离关注点)。
第二件事是在它被传递的地方使用@Qualifiers("id of declared bean")。
【讨论】:
【参考方案3】:使用过滤器将其从组件扫描中排除
<component-scan base-package="your-package">
<exclude-filter type="regex" expression="DefaultService" />
</component-scan>
不确定是否有办法只使用注释(除了从 DefaultService 中删除 @Service 注释)。
【讨论】:
谢谢,Wilhelm,我相信您的解决方案会奏效。但随后我将不得不自己扫描我的服务。好主意!【参考方案4】:要么明确定义服务 bean
<bean id="myService" class="x.y.z.SpecializedService" />
或组件扫描它。
在任何一种情况下,在您的应用程序上下文中,避免显式定义 DefaultService 并避免对其进行组件扫描。
【讨论】:
谢谢,威利。我们最终得到了您的解决方案,因为我们还出于维护原因(我们正在谈论数百个服务)决定将每个服务的列表保存在一个文件中 - 即 spring bean 配置。只定义 id 和 classname 并不会太痛苦,因为只使用注解更诱人。以上是关于如何按名称覆盖 Spring 服务 bean,仅使用注释的主要内容,如果未能解决你的问题,请参考以下文章