规则引擎(Apache camel) 学习八
1.Service与生命周期
在Apache Camel中有一个比Endpoint、Component、CamelContext等元素更基础的概念元素:Service。
Camel官方文档中对Service的解释是:
Camel uses a simple lifecycle interface called Service which has a single start() and stop() method.
Various classes implement Service such as CamelContext along with a number of Component and Endpoint classes.
When you use Camel you typically have to start the CamelContext which will start all the various components and endpoints
and activate the routing rules until the context is stopped again.
......
说明:包括Endpoint、Component、CamelContext等元素在内的大多数工作在Camel中的元素,都是一个一个的Service。
例如,我们虽然定义了一个JettyHttpComponent(就是在代码中使用DSL定义的”jetty:http://0.0.0.0:8282/directCamel“头部所表示的Component),
但是我们想要在Camel应用程序运行阶段使用这个Component,就需要利用start方法将这个Component启动起来。
实际上通过阅读org.apache.camel.component.jetty.JettyHttpComponent的源代码,
读者可以发现JettyHttpComponent的启动过程起始大多数情况下什么都不会做,
只是在org.apache.camel.support.ServiceSupport中更改了JettyHttpComponent对象的一些状态属性。
倒是HttpConsumer这个Service,在启动的过程中启动了JettyHttpComponent对象的连接监听,
并建立了若干个名为【qtp-*】的处理线程。下图为读者展示了org.apache.camel.Service接口的主要继承/实现体系:


Service有且只有两个接口方法定义:start()和stop(),这两个方法的含义显而易见,启动服务和终止服务。
另外继承自Service的另外两个子级接口SuspendableService、ShutdownableService分别还定义了另外几个方法:
suspend()、resume()和shutdown()方法,分别用来暂停服务、恢复服务和彻底停止服务
(彻底停止服务意味着在Camel应用程序运行的有生之年不能再次启动了)。
注意:每个Service的生命周期都是独立的,其实start(),结束stop()
Camel应用程序中的每一个Service都是独立运行的,各个Service的关联衔接通过CamelContext上下文对象完成。
每一个Service通过调用start()方法被激活并参与到Camel应用程序的工作中,直到它的stop()方法被调用。
也就是说,每个Service都有独立的生命周期。(http://camel.apache.org/lifecycle.html)
注意:对于每个service是独立的,为了便于服务启动,引入了上下文对象CamelContext
那么问题来了,既然每个Service都有独立的生命周期,我们启动Camel应用程序时就要启动包括Route、Endpoint、Component、
Producer、Consumer、LifecycleStrategy等概念元素在内的无数多个Service实现,那么作为开发人员不可能编写代码一个一个的Service
来进行启动(大多数开发人员不了解Camel的内部结构,也根本不知道要启动哪些Service)。
那么作为Camel应用程序肯定需要提供一个办法,在应用程序启动时分析应用程序所涉及到的所有的Service,
并统一管理这些Service启动和停止的动作。这就是CamelContext所设计的另一个功能。
2.CamelContext上下文
介绍:CamelContext从英文字面上理解,是Camel服务上下文的意思。
CamelContext在Apache Camel中的重要性,就像ApplicationContext之于Spring、ServletContext之于Servlet……
但是包括Camel官方文档在内的,所有读者能够在互联网上找到的资料对于CamelContext的介绍都只有聊聊数笔。
官网翻译:
The context component allows you to create new Camel Components from a CamelContext with a number of routes
which is then treated as a black box, allowing you to refer to the local endpoints within the component from other CamelContexts.
First you need to create a CamelContext, add some routes in it, start it and then register the CamelContext into
the Registry (JNDI, Spring, Guice or OSGi etc).
………
说明:以上是Camel官方文档对于CamelContext作用的一些说明,大致的意思是说CamelContext
横跨了Camel服务的整个生命周期,并且为Camel服务的工作环境提供支撑。
3.CamelContext实现结构
介绍:那么CamelContext中到底存储了哪些重要的元素,又是如何工作的呢?
看样子官方的使用手册中并没有说明,
我们还是通过分析CamelContext的源代码来看看它的一些什么内容吧。
下面我们应用已经讲解过的Apache Camel相关知识,
对org.apache.camel.CamelContext接口以及它的主要实现类进行分析,
以便尽可能的去理解为什么CamelContext非常重要。
源码分析:

注:如何和Spring无缝嵌合
上图是Apache Camel中实现了org.apache.camel.CamelContext接口的主要类。
其中有两个实现类需要特别说明一下:SpringCamelContext和DefaultCamelContext。
Camel可以和Spring框架进行无缝集成。
例如可以将您的某个Processor处理器以Spring Bean的形式注入到Spring Ioc容器中,
然后Camel服务就可以通过在Spring Ioc容器中定义的bean id(XML方式或者注解方式都行)
取得这个Processor处理器的实例。
实现示例:
为了实现以上描述的功能,需要Camel服务能够从Spring的ApplicationContext取得Bean,
而SpringCamelContext可以帮助Camel服务完成这个关键动作:
通过SpringCamelContext中重写的createRegistry方法创建一个ApplicationContextRegistry实例,
并通过后者从ApplicationContext的“getBean”方法中获取Spring Ioc容器中符合指定的Bean id的实例。
这就是Camel服务和Spring进行无缝集成的一个关键点,如以下代码片段所示:
public class SpringCamelContext extends DefaultCamelContext
implements InitializingBean, DisposableBean, ApplicationContextAware {
......
@Override
protected Registry createRegistry() {
return new ApplicationContextRegistry(getApplicationContext());
}
......
}
public class ApplicationContextRegistry implements
Registry {
......
@Override
public Object lookupByName(String name) {
try {
return applicationContext.getBean(name);
} catch (NoSuchBeanDefinitionException e) {
return null;
}
}
......
}
另外一个需要说明的是DefaultCamelContext类,
这个类是我们在前文涉及到Camel示例代码时使用最多的CamelContext实现。
而我们将要分析的CamelContext工作原理也基本上是在这个类中进行了完整的实现
其子类只是根据不同的Camel运行环境重写了其中某些方法(例如之前提到的createRegistry方法)。

浙公网安备 33010602011771号