Camel从3.9.x升级3.11.x时@Uri标注FluentProducerTemplate注入JAXRS Bean失败
问题解答
1. CdiCamelExtension启动顺序变更说明
Camel 3.10及以上版本的CdiCamelExtension确实存在相关逻辑调整,完全可以解释你遇到的启动顺序问题:
3.9.x及更早版本中,@Uri限定的FluentProducerTemplate/ProducerTemplate等Bean的元数据注册逻辑,是放在CDI部署周期的BeforeBeanDiscovery阶段执行,会早于所有业务Bean的初始化流程。3.10版本为了支持多CamelContext动态配置、自定义限定符扩展等新特性,将这部分Bean的注册逻辑后移到了AfterDeploymentValidation阶段。
而Wildfly 22内置的Weld 4.x版本同时调整了JAX-RS Bean的初始化时机,早于Camel的Bean注册阶段,就会出现Weld初始化JAX-RS Bean时找不到@Uri限定的FluentProducerTemplate依赖的报错。
2. 解决方案
方案1:提前触发Camel相关组件初始化
- 给所有自定义的RouteBuilder实现类添加
@Priority(1)注解,优先级数值越小初始化顺序越靠前,Camel CDI会优先加载高优先级的路由定义,提前触发CamelContext的全量初始化。 - 给你自定义的CamelContext生产方法添加
@Startup注解,强制容器在应用启动阶段就完成CamelContext的初始化,而非等到首次注入时才懒加载:
@Produces @ApplicationScoped @Startup public final CamelContext createContext() { ... }
- 3.11.x版本新增了兼容配置项
camel.cdi.early-start,在你的application.properties中配置为true,即可恢复3.9.x版本的提前注册逻辑,直接解决依赖找不到的问题。
方案2:延迟JAX-RS Bean的依赖注入
不需要依赖EJB的@DependsOn,纯CDI环境下可以通过以下方式实现依赖等待:
- 用CDI的
Instance接口实现懒加载,调整注入代码如下,实际调用时再获取实例即可避免启动阶段依赖校验失败:
@Path("/demo") public class MyJaxRsWebServices { @Inject @Uri("direct:...") private Instance<FluentProducerTemplate> endpointInstance; // 业务方法中调用endpointInstance.get()获取实例使用 }
- 给JAX-RS Bean添加CamelContext初始化事件监听,保证Camel完全启动后再初始化相关依赖:
@Path("/demo") public class MyJaxRsWebServices { @Uri("direct:...") private FluentProducerTemplate endpoint; public void onCamelReady(@Observes @Initialized(ApplicationScoped.class) CamelContext context) { // 此处手动获取endpoint实例赋值即可 endpoint = context.createFluentProducerTemplate("direct:..."); } }
内容的提问来源于stack exchange,提问作者TacheDeChoco
相关产品推荐
相关产品推荐

