我正在使用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被实例化并注入我的应用程序。
@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被实例化(在私有方法 afterPropertiesSet中完成)
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组件有些可疑。
答案 0 :(得分:1)
我解决这个问题有点快(我想在两天前发布这个^^),但是一位同事发现了可能出现的问题。
当使用 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 似乎也是一个问题,不推荐使用,他们声称已弃用。
所以,不要为你的骆驼管理的bean做过DI(无论是通过属性还是构造函数注入),或者跳过那个启动器。
答案 1 :(得分:0)
问题是Map<String,Object>
对于Spring来说太模糊了,无法理解你想要的东西;我认为默认行为是它会给你所有按名称键入的bean。
相反,更具体,或者可能提供必要的参数作为构造函数参数,并在@Bean
方法中显式配置它们(无论如何总是使用构造函数注入是个好主意。)