7

鉴于我有一个 Spring bean 配置为

@Service("myService")
public class DefaultService extends MyService {
}

和一个使用这个 bean 的类

public class Consumer {
    @Autowired
    @Qualifier("myService")
    private MyService service;
    ...
}

我现在希望我的项目(包括前面的类)有Consumer另一个MyService被注入的实现。因此我想覆盖beanmyService

@Service("myService")
public class SpecializedService implements MyService {
}

导致Consumer现在携带一个实例SpecializedService而不是DefaultService。根据定义,我不能在 Spring 容器中拥有两个同名的 bean。我怎么能告诉春天,新服务的定义将覆盖旧服务?我不想修改Consumer课程。

4

4 回答 4

3

要么明确定义服务 bean

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

或组件扫描它。

无论哪种情况,在您的应用程序上下文中,避免显式定义 DefaultService 并避免组件扫描它。

于 2011-04-07T04:54:23.033 回答
2

使用过滤器将其从组件扫描中排除

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

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

于 2011-04-07T05:25:57.563 回答
0

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

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

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

第二件事是在传递它的地方使用 @Qualifiers("id of declared bean") 。

于 2014-12-25T15:45:04.977 回答
-3

我知道,已经晚了。还是贴吧。

对于 MyService 的不同实现,您应该有不同的名称。

例如

@Service("mySpecializedService")
public class SpecializedService implements MyService {
}

@Service("myService")
public class DefaultService extends MyService {
 }

在自动装配它们时(比如在 Controller 中),您可以使用 @Qualifier 注入所需的实现,如下所述。

获取默认实现

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

获得专门的实施

@Autowired
@Qualifier("mySpecializedService")
MyService myService;
于 2017-09-21T03:15:42.240 回答