我正在尝试收集与Camel seda://路由相连的并发使用者的运行时统计信息。每个使用者都使用Spring“原型” Bean中的相同的Camel Processor Bean,因为我希望每个使用者都可以在其自己的线程中独立进行操作。 Camel文档指出,使用seda://和并发使用者将在其自己的线程中运行每个使用者。这似乎运行良好,当我运行该进程时,可以看到4个SyncQueueProcessor线程。
要收集统计信息,我有一个单独的Spring Bean(Singleton),可以将其自动连线到Camel“原型”处理器,然后在处理器中有代码来跟踪运行时。我正在使用当前线程ID来标识每个并发的使用者处理器:我在ProcessStatistics单例Bean的@Autowired setter方法中设置routeId:我想在创建原型时将setter方法称为ONCE。>
@Component
public class EnrichDocumentRoute extends RouteBuilder {
private SyncQueueProcessor syncQueueProcessor;
@Value("${data-sync.processor.concurrency: 3}")
private int concurrency;
@Override
public void configure() throws Exception {
from("seda:processQueue?concurrentConsumers=" + concurrency)
.routeId("enrichment")
.log(LoggingLevel.DEBUG, "##### Started Enrichment Process for : ${body.billingDocumentIdentifier}")
.process(this.getSyncQueueProcessor())
.log(LoggingLevel.DEBUG, "##### Finished Enrichment Process for: ${body.billingDocumentIdentifier}")
.end()
;
}
@Autowired
public void setSyncQueueProcessor(SyncQueueProcessor syncQueueProcessor) {
this.syncQueueProcessor = syncQueueProcessor;
}
public SyncQueueProcessor getSyncQueueProcessor() {
counter++;
LOG.info("getSyncQueueProcessor() - Factory sync-consumer [" + counter + "]");
//return this.syncQueueProcessorFactory.getObject("sync-consumer-"+this.counter);
//return new SyncQueueProcessor("sync-consumer-"+this.counter);
//SyncQueueProcessor lnewProcessor = new SyncQueueProcessor();
//lnewProcessor.setRouteId("sync-consumer-"+this.counter);
//return lnewProcessor;
//return new SyncQueueProcessor();
return syncQueueProcessor;
}
@Component
@Scope("prototype")
@Qualifier("syncQueueProcessor")
public class SyncQueueProcessor implements Processor {
// BEAN : Spring Singleton Bean To collect statistics
private ProcessStatistics processStatistics;
// POJO : Collects the Time statistics, POJO is added to the
// Spring Singleton bean in the setter method...
private ProcessStatisticsBean processStatisticsBean;
private String routeId;
@Autowired
public void setProcessStatistics(ProcessStatistics setValue) {
this.processStatistics = setValue;
this.processStatisticsBean = new ProcessStatisticsBean ();
getProcessStatisticsBean().setRouteId("sync-consumer-" + Thread.currentThread().getId());
getProcessStatisticsBean().setEndpointId(getRouteId());
this.processStatistics.addItem(this.processStatisticsBean);
}
我遇到的问题是,当我运行该进程时,我只看到一个sync-consumer-23 ...我希望在统计信息中看到4条sync-consumer-nn路由。对于单个sync-processor-nn,我确实在ProcessStatistics中看到正在收集时间统计信息。
但是为什么其他三个消费者没有出现呢?我认为“原型”范围将允许setter方法针对每个Bean一次运行...因此,每个都在其自己的线程中。
我尝试过的事情: -在课程开始时设置routeId ...没什么区别。
tia,adym
UPDATE:好吧,我想我回答了一个问题,之所以在stats bean中只看到1是因为只将setter称为ONCE ...看完这篇文章How to let Spring initialize "prototype" beans only when it is got through getBean()?之后,我猜骆驼之路是这的原因...即一个Singleton bean(骆驼之路)导致原型被初始化。
也许更好的问题是,在分配线程后如何运行原型bean的初始化?
更新:如本文所述,使用ObjectProvider进行了尝试...结果相同:Spring Java Config: how do you create a prototype-scoped @Bean with runtime arguments?。此外,EnrichDocumentRoute.getSyncQueueProcessor()中的其他失败尝试(已注释掉)...