上篇Camel启动路由过程中讲到启动Consumer,调用了DefaultCamelContext.startService(service)方法,下面是方法源码:
private void startService(Service service) throws Exception {
if (service instanceof StartupListener) {
StartupListener listener = (StartupListener) service;
addStartupListener(listener);
}
service.start();
}
上面方法中调用了service的start()方法,在我们的示例中,这个service对象其实是FileConsumer对象,FileConsumer继承关系如下:
FileConsumer extends GenericFileConsumer<File> extends ScheduledBatchPollingConsumer extends ScheduledPollConsumer extends DefaultConsumer extends ServiceSupport, FileConsumer的start()方法是从ServiceSupport继承而来,在ServiceSupport的start()方法中调用了doStart()方法,而FileConsumer的doStart()方法又是从GenericFileConsumer继承而来,GenericFileConsumer又调用父类ScheduledPollConsumer的doStart()方法,这里经过一系列的多态方法调用。
最重要的就是ScheduledPollConsumer的doStart()方法:
protected void doStart() throws Exception {
//先调用父类的doStart()方法
super.doStart();
//省略...
//如果调用器为空,则创建一个
if (scheduler == null) {
scheduler = new DefaultScheduledPollConsumerScheduler();
}
scheduler.setCamelContext(getEndpoint().getCamelContext());
//设置scheduler的consumer成员变量
scheduler.onInit(this);
//设置scheduler的task成员变量
scheduler.scheduleTask(this);
//省略...
//启动scheduler,该方法调用了DefaultScheduledPollConsumerScheduler的doStart()方法
//为scheduler获取java.util.concurrent.ScheduledExecutorService,即线程池
//因为要轮询文件肯定是要开启新的线程的,所以需要一个线程池对象
ServiceHelper.startService(scheduler);
if (isStartScheduler()) {
//运行scheduler
startScheduler();
}
}