我正在使用 Spring Boot 1.5.7 和 Apache Camel 2.19.3,使用 spring-boot-starter-camel 提供的 Spring Boot AutoConfiguration
这是非常基本的 Spring Boot 和 Camel 初始化,如 tutorial 所示。 ,所以我们有一个 RouteBuilder 组件来完成这个任务。
@Component
public class CIFRoutes extends RouteBuilder {
@Override
public void configure() throws Exception {
// build routes
}
}
我们有一个配置,它定义了我们应用程序中需要的一些bean
@Configuration
public class MyConfiguration {
@Bean
public void Map<String, Object> map() {
return new HashMap<>()
}
}
最后,我们有一个自定义的 InflightRepository 实现,应该通过自动配置扫描并添加到 CamelContext 中,该实现基本上可以工作,但由于某种原因,该组件没有无法正确初始化。意味着,它的依赖项没有初始化,但 bean 被实例化并注入(inject)到我的应用程序中。
@Component
public class MyCustomInflightRepository extends DefaultInflightRepository {
@Autowired
private Map<String, Object> map;
@Override
public void add(Exchange exchange) {
super.addExchange(exchange);
// ....
}
}
现在的问题是map仍然(null),我也尝试添加一个@PostConstruct初始化方法,但它没有被调用。
据我能够重建,它似乎与 CamelAutoConfiguration 中的过早连接有关,其中 CamelContext bean 被实例化(在私有(private)方法 afterPropertiesSet 中完成) 。
InflightRepository inflightRepository = getSingleBeanOfType(applicationContext, InflightRepository.class);
if (inflightRepository != null) {
LOG.info("Using custom InflightRepository: {}", inflightRepository);
camelContext.setInflightRepository(inflightRepository);
}
如果MyCustomInflightRepository没有实现InflightRepository,bean会正确初始化,但实际上Camel无法识别。禁用自动配置时,将注入(inject) bean 的依赖项。
所以,要么我正在做按照 Spring 标准不可能完成的事情,要么 Spring 的 Camel 组件有些可疑。
最佳答案
我解决这个问题的速度有点快(我两天前就想发布这个了^^),但一位同事找出了可能是什么问题。
当使用 CamelAutoConfiguration 的 InflightRepository bean(或者实际上 Camel 尝试在此处获取匹配 bean 的所有内容)时,会在属性解析器完全初始化之前访问上下文导致 bean 在解析任何自动连接属性之前被初始化(并缓存在上下文中)。
我不是 Spring 专家,但我认为这种行为有点问题,因为当您依赖 Spring DI 作为自定义组件时,未初始化的 bean 会被拉入 CamelContext 中。
当然,我会向维护者提出这个问题......
顺便说一句,我的简单解决方案是在上下文配置中手动设置运行中存储库(按照建议)
@Bean
public CamelContextConfiguration camelConfig() {
return new CamelContextConfiguration() {
@Override
public void beforeApplicationStart(CamelContext context) {
context.setInflightRepository(new MyCustomInflightRepository(/* Dependencies go here */ ));
}
@Override
public void afterApplicationStart(CamelContext camelContext) {
}
};
}
此外,在您的项目中使用camel-http-starter时,这似乎是一个问题,不推荐使用它,他们声称它已被弃用。
因此,要么不要为您的 Camel 管理的 Bean 执行 DI(无论是通过属性还是构造函数注入(inject)),要么跳过该启动程序。
关于java - Spring Boot Camel - Camel 组件中的 Autowiring 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46680985/