Camel 2.21.2:CamelSpringRunner+JavaConfig下MockEndpoints注入失效如何解决?
我之前在Camel 2.x的纯Spring(非Boot)测试场景里也踩过类似的坑,咱们来一步步拆解解决:
问题根源
你提到的CamelSpringDelegatingTestContextLoader能正常工作,是因为它内部额外做了Camel上下文与Spring容器的绑定逻辑,但官方废弃它的原因是CamelTestContextBootstrapper已经接管了这部分工作,重复使用会导致冗余初始化。而去掉它后出现的装配失败,本质是Spring默认的上下文加载器没有正确识别CamelConfiguration生成的CamelContext,或者CamelTestContextBootstrapper的初始化逻辑没有被正确触发。
可行解决方案
方案1:调整注解组合,移除冗余配置
首先要明确:CamelSpringRunner已经默认集成了CamelTestContextBootstrapper的功能,你不需要额外添加@BootstrapWith(CamelTestContextBootstrapper.class)注解,重复声明反而可能干扰上下文初始化。同时使用Spring原生的AnnotationConfigContextLoader作为加载器,配合你的JavaConfig类即可:
修改后的测试类代码:
@RunWith(CamelSpringRunner.class) @MockEndpoints @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) @ContextConfiguration(loader = AnnotationConfigContextLoader.class, classes = MyTest.TestConfig.class) public class MyTest { @Autowired protected CamelContext camelContext; @Produce(uri = "direct:in") private ProducerTemplate input; // 测试方法... @Configuration static class TestConfig extends CamelConfiguration { @Override protected void configure() throws Exception { // 这里保留你的路由配置,比如配合@MockEndpoints的示例路由 from("direct:in") .to("mock:out"); } } }
方案2:显式声明CamelContext Bean(保险兜底)
如果方案1还是出现装配问题,可能是CamelConfiguration的自动配置在你的环境中未生效,这时可以在TestConfig里显式声明CamelContext的Bean,确保Spring容器能明确扫描到:
@Configuration static class TestConfig extends CamelConfiguration { @Bean @Override public CamelContext camelContext() throws Exception { return super.camelContext(); } @Override protected void configure() throws Exception { // 你的路由配置逻辑 } }
方案3:使用@CamelContextConfiguration注解(更贴合Camel测试规范)
Camel提供了@CamelContextConfiguration注解专门配置测试用的Camel上下文,你可以用它替代继承CamelConfiguration的方式,逻辑更清晰:
@RunWith(CamelSpringRunner.class) @MockEndpoints @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) @ContextConfiguration(loader = AnnotationConfigContextLoader.class) @CamelContextConfiguration public class MyTest { @Autowired protected CamelContext camelContext; @Produce(uri = "direct:in") private ProducerTemplate input; // 配置Camel上下文的方法 @Before public void setupCamelContext(CamelContext context) throws Exception { context.addRoutes(new RouteBuilder() { @Override public void configure() throws Exception { from("direct:in") .to("mock:out"); } }); } // 测试方法... }
为什么CamelBootSpringRunner能工作?
CamelBootSpringRunner是针对Spring Boot环境优化的,它会自动触发Spring Boot的自动配置机制,其中包含了Camel上下文的自动装配逻辑,所以不需要额外配置就能正常工作,但确实会引入Spring Boot的依赖,不符合你不想冗余引入的需求。
注意事项
- 确保测试类和配置类在同一个包下,或者通过
@ContextConfiguration的classes属性明确指定(你已经这么做了,这点没问题) - 检查Camel的
spring-test依赖是否正确引入,版本要和Camel核心版本保持一致(2.21.2)
内容的提问来源于stack exchange,提问作者antidote

