如何仅使用注释按名称覆盖SpringServiceBean

如何仅使用注释按名称覆盖SpringServiceBean,spring,javabeans,overwrite,autowired,inject,Spring,Javabeans,Overwrite,Autowired,Inject,假设我有一个配置为 @Service("myService") public class DefaultService extends MyService { } 和一个使用这个bean的类 public class Consumer { @Autowired @Qualifier("myService") private MyService service; ... } 现在,我希望我的项目(包括前面的类)能够注入Consumer另一个MyService实现

假设我有一个配置为

@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。我如何告诉spring,新服务的定义将覆盖旧服务?我不想修改
使用者
类。

或者显式定义服务bean

<bean id="myService" class="x.y.z.SpecializedService" />

或者组件扫描它


在这两种情况下,在应用程序上下文中,避免显式定义DefaultService,并避免组件扫描它。

通过使用筛选器将其从组件扫描中排除

<component-scan base-package="your-package">
    <exclude-filter type="regex" expression="DefaultService" />
</component-scan>


不确定是否有办法只使用注释(而不是从DefaultService中删除@Service注释)。

基于注释的连接发生在基于XML的配置之前,这意味着在XML中定义的bean将 覆盖那些由注释完成的连接。 因此,用XML明确地定义它,就像Willie所说的那样,就可以了

<bean id="myService" class="x.y.z.SpecializedService" />

Spring建议对服务和存储库bean使用XML,对MVC bean使用注释。它还建议@Autowired不进行组件扫描。但是注释通常是被鼓励的,尽管它将代码和配置合并在一起(反对关注点的分离)


第二件事是在传递的地方使用@Qualifiers(“声明bean的id”)。

我知道,已经很晚了。还在贴

对于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;
得到专门的实施

@Autowired
@Qualifier("myService")
MyService myService;   
@Autowired
@Qualifier("mySpecializedService")
MyService myService;

谢谢,威廉,我相信你的解决办法会奏效的。但是我必须自己扫描我的服务。好主意!谢谢,威利。我们最终得到了您的解决方案,因为出于维护原因(我们谈论的是数百个服务),我们决定将每个服务的列表保存在一个文件中,即Springbean配置。只定义id和类名并不太痛苦,因为只使用注释更具诱惑力。这与OP要求的完全相反。我会在单独的配置文件(xml或java)中定义新bean而不是另一个,并让它覆盖上一个,或者使用Spring概要文件或@Conditional。