Spring Boot Camel-Camel组件中的自动布线问题



我使用的是Spring Boot 1.5.7和Apache Camel 2.19.3,使用的是Spring Boot starter Camel提供的Spring Boot自动配置

这是非常基本的Spring Boot和Camel初始化,就像他们的教程中一样,所以我们有一个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被实例化并注入到我的应用程序中。

@Component
public class MyCustomInflightRepository extends DefaultInflightRepository {
@Autowired
private Map<String, Object> map;
@Override
public void add(Exchange exchange) {
super.addExchange(exchange);
// ....
}
}

现在的问题是,映射仍然是(null),我还尝试添加@PostConstruct初始值设定项方法,但它没有被调用。

就我所能重建的而言,它似乎与CamelAutoConfiguration中的早熟有关,其中CamelContextbean被实例化(在PropertiesSet之后的私有方法中完成)。

InflightRepository inflightRepository = getSingleBeanOfType(applicationContext, InflightRepository.class);
if (inflightRepository != null) {
LOG.info("Using custom InflightRepository: {}", inflightRepository);
camelContext.setInflightRepository(inflightRepository);
}

如果MyCustomInflightRepository没有实现InflightRepository,则bean被正确初始化,但Camel确实无法识别。禁用自动配置时,将注入bean的依赖项。

所以,按照Spring的标准,要么我在做不可能的事情,要么Spring的Camel组件有问题。

我解决这个问题有点快(两天前我就想发布这个),但一位同事发现了问题所在。

当使用CamelAutoConfigurationInflightRepositorybean(或者实际上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似乎也是一个问题,这是不推荐的,他们声称它是不推荐使用的。

因此,要么不为骆驼管理的bean执行DI(无论是通过属性还是构造函数注入),要么跳过该启动器。

问题是Map<String,Object>太模糊,Spring无法理解您想要什么;我认为默认行为是,它将为您提供所有按名称键控的bean。

相反,要更具体,或者可能提供必要的参数作为构造函数参数,并在@Bean方法中显式配置它们(无论如何,始终使用构造函数注入是个好主意)。

最新更新