java - 如何在保留参数的同时覆盖spring bean?
问题描述
我有两个项目,库和应用程序。库定义了一个 CommonService 接口,我想在应用程序中覆盖它。我使用 Spring XML 进行配置。库代码:
public interface CommonService {
String service();
}
public class CommonServiceImpl implements CommonService {
private String message;
// + getter/setter
@Override
public String service() {
return "Message: " + getMessage();
}
}
申请代码:
public class OverriddenServiceImpl extends CommonServiceImpl {
@Override
public String service() {
return "Overridden: " + super.service();
}
}
库配置(lib-config.xml):
<bean id="commonService" class="spring.context.test.library.CommonServiceImpl">
<property name="message" value="Hello!" />
</bean>
应用程序配置(app-config.xml):
<import resource="classpath:/lib-config.xml"/>
<bean id="commonService"
class="spring.context.test.application.OverriddenServiceImpl">
</bean>
测试:
@Test
void testLibraryXML() {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:/lib-config.xml");
CommonService commonService = context.getBean("commonService", CommonService.class);
assertEquals("Message: Hello!", commonService.service());
}
@Test
void testApplicationXML() {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:/app-config.xml");
CommonService commonService = context.getBean("commonService", CommonService.class);
// FIXME!! this gives Overridden: Message: null
assertEquals("Overridden: Message: Hello!", commonService.service());
}
问题在于 testApplicationXML:commonService 应该返回“覆盖:消息:Hello!”,但它返回“覆盖:消息:null”。
我已将所有代码放到 github(为简单起见,库和应用程序都在一个项目中): https ://github.com/mateattila/spring-test-sandbox
我发现 Spring 实例化了 OverriddenServiceImpl 但没有从以前的定义中继承参数。我尝试过使用 bean 继承,但在这种情况下,我必须使用不同的 bean id,我想避免它。我尝试使用基于注释的配置并且它可以工作,但它会产生很多开销(请参阅 OverriddenConfiguration 和 testApplicationAnnotation)。
任何想法如何用 Spring 处理这个要求?我也对如何扩展 Spring 使其像这样工作感兴趣。
解决方案
在跟进@M.Deinum 的评论后,我找到了非常简单的解决方案:使用 bean 名称而不是 bean id。名称覆盖工作正常。我已将修复提交到github 存储库,无论如何,这里是:
lib-config.xml:
<bean id="commonService" name="service"
class="spring.context.test.library.CommonServiceImpl">
<property name="message" value="Hello!" />
</bean>
app-config.xml:
<bean id="commonService2" name="service"
class="spring.context.test.application.OverriddenServiceImpl"
parent="commonService">
</bean>
通过测试:
@Test
void testApplicationXML_FIXED() {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:/app-config.xml");
CommonService commonService = context.getBean("service", CommonService.class);
assertEquals("Overridden: Message: Hello!", commonService.service());
}
推荐阅读
- mongodb - 一键求和求和
- javascript - React-Native 将循环中的结果累积到单个字符串
- machine-learning - 如何在 Pytorch 中实现元训练步长?
- ios - 如何使用 Voice Over 确定当前聚焦的 UITableViewCell 的索引路径?
- c - 使用显示错误值的双数组中的值的平均函数
- r - 将基于新数据的折线图添加到一系列箱线图
- javascript - Nest JS无法读取未定义的属性
- r - 如何在 R 中使用 ggplot2 根据大小为节点/geom_point 着色?
- python - 如何删除错误“TypeError: can't concat str to bytes”
- python - 在 python GUI 中显示图像时出现问题