如何按名称覆盖 Spring 服务 bean,仅使用注释
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5576128/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to overwrite Spring service beans by name, using annotations only
提问by Lars Blumberg
Given I have a Spring bean configured as
鉴于我有一个 Spring bean 配置为
@Service("myService")
public class DefaultService extends MyService {
}
and a class using this bean
和一个使用这个 bean 的类
public class Consumer {
@Autowired
@Qualifier("myService")
private MyService service;
...
}
I now want my project, that includes the preceding classes, to have Consumeranother implementation of MyServicebeing injected. Therefore I would like to overwrite the bean myService
我现在希望我的项目,包括前面的类,有Consumer另一个MyService被注入的实现。因此我想覆盖beanmyService
@Service("myService")
public class SpecializedService implements MyService {
}
resulting in Consumercarrying now an instance of SpecializedServiceinstead of DefaultService. By definition I cannot have two beans with the same name in the Spring container. How can I tell spring, that the definition of the new service shall overwrite the older one? I don't want to modify the Consumerclass.
导致Consumer现在携带一个SpecializedService而不是的实例DefaultService。根据定义,Spring 容器中不能有两个同名的 bean。我怎么能告诉 spring,新服务的定义将覆盖旧服务?我不想修改Consumer课程。
采纳答案by Lars Blumberg
Either define the service bean explicitly
明确定义服务bean
<bean id="myService" class="x.y.z.SpecializedService" />
or component-scan it.
或组件扫描它。
In either event, in your application context, avoid explicitly defining DefaultService and avoid component-scanning it.
无论哪种情况,在您的应用程序上下文中,都应避免显式定义 DefaultService 并避免对其进行组件扫描。
回答by Wilhelm Kleu
Exclude it from component-scan by using a filter
使用过滤器将其从组件扫描中排除
<component-scan base-package="your-package">
<exclude-filter type="regex" expression="DefaultService" />
</component-scan>
Not sure if there is a way to do it with only annotations (other than removing the @Service annotation from DefaultService).
不确定是否有办法只使用注释(除了从 DefaultService 中删除 @Service 注释)。
回答by vimal krishna
Annotation based wiring happens before the XML based configuration, that means beans defined in XML will overwrite those wiring done by Annotations. So defining it explicitely in XML, like Willie has said will do the work
基于注解的连接发生在基于 XML 的配置之前,这意味着在 XML 中定义的 bean 将覆盖那些由注解完成的连接。所以在 XML 中明确定义它,就像威利所说的那样
<bean id="myService" class="x.y.z.SpecializedService" />
Spring recommends using XML for service and repository beans and annotation for MVC beans. It also recommends @Autowired without component scanning. But Annotation are in general encouraged, although it merges code and configuration together (against seperation of concerns).
Spring 建议对服务和存储库 bean 使用 XML,对 MVC bean 使用注解。它还建议在没有组件扫描的情况下使用 @Autowired。但是通常鼓励注解,尽管它将代码和配置合并在一起(反对关注点分离)。
Second thing is to use @Qualifiers("id of declared bean") where it is being passed.
第二件事是在它被传递的地方使用 @Qualifiers("id of Declaration bean") 。
回答by Gyro
I know , its late . Still posting it.
我知道,已经晚了。还是发一下吧。
You should have different names for different implementations of MyService.
您应该为 MyService 的不同实现使用不同的名称。
For instance
例如
@Service("mySpecializedService")
public class SpecializedService implements MyService {
}
@Service("myService")
public class DefaultService extends MyService {
}
While autowiring them ( say in Controller) , you may use @Qualifier to inject desired implementation as mentioned below.
在自动装配它们时(例如在 Controller 中),您可以使用 @Qualifier 注入所需的实现,如下所述。
To get default implementation
获取默认实现
@Autowired
@Qualifier("myService")
MyService myService;
To get specialized implementation
获得专门的实施
@Autowired
@Qualifier("mySpecializedService")
MyService myService;

