Stapler
Stapler 是一个将应用程序对象和 URL 装订在一起的 lib 库,使编写 web 应用程序更加方便。Stapler 的核心思想是自动为应用程序对象绑定 URL,并创建直观的 URL 层次结构。
下图显示了 Stapler 的工作原理:
上图左边显示了应用程序的代码信息,右边显示了 URL 的层次结构。通过反射机制,Stapler 可以将 URL 绑定到应用程序对象。比如说,应用程序的根对象对应 URL 的根“/”。通过 getProject(“stapler”) 方法访问的对象将分派给 URL “/project/stapler”。通过这种方式,应用程序对象模型就直接转化为 URL 的层次结构, 如图中紫色箭头所示。
Jenkins 的类对象和 URL 绑定就是通过 Stapler 来实现的。Hudson 实例作为 root 对象绑定到 URL“/”,其余部分则根据对象的可达性来绑定。例如 Hudson 有一个 getJob(String) 方法,那么根据上图的介绍,可以知道 URL“/job/foo/”将绑定到 Hudson.getJob(“foo”) 返回的对象。
Jelly
Jelly 是一种基于 Java 技术和 XML 的脚本编制和处理引擎。Jelly 的特点是有许多基于 JSTL (JSP 标准标记库,JSP Standard Tag Library)、Ant、Velocity 及其它众多工具的可执行标记。Jelly 还支持 Jexl(Java 表达式语言,Java Expression
Language),Jexl 是 JSTL 表达式语言的扩展版本。
Jenkins的界面绘制就是通过Jelly实现的。Jelly文件位于resources目录下,如下图所示
首页文件渲染文件位于lib/layout/layout.jelly,引用示例如下,l:yui引用当前目录下的yui.jelly进行渲染,查看yui.jelly内容,可以知道此处为引用yui-js文件的代码:
持久化
Jenkins 使用文件来存储数据(所有数据都存储在$JENKINS_HOME)。有些数据,比如 console 输出,会作为文本文件存储;有些数据则会像 Java 配置文件格式一样存储;大多数的结构数据,如一个项目的配置或构建(build)记录信息则会通过 XStream
持久化,实际如图 3 所示。从图中可以看到 Jenkins 把一个 Job 的所有构建记录都通过 XStream 记录下来。
插件
Jenkins 的对象模型是可扩展的,通过 Jenkins 提供的可扩展点,我们可以开发插件扩展 Jenkins 的功能。到目前为止,Jenkins 已经支持超过 600 个插件,这些插件支持的功能涵盖了软件配置管理 (SCM)、软件测试、通知 (Notification)、报表等方面。
Jenkins 通过单独的类加载器加载每个插件以避免插件之间产生冲突。插件就像 Jenkins 内置的其他类一样参与到系统的活动中。另外,插件可以通过 XStream 持久化,可以由 Jelly 提供视图技术,可以提供图片等静态资源,插件中所有的功能可以无缝的加入到 Jenkins 内置的功能上。
Jenkins入口文件
Jenkins 代码的入口是下图所示的 WebAppMain 类,位于 hudson(package) 下面
类 WebAppMain 实现了 ServletContextListener 接口。该接口的作用主要是监听 ServletContext 对象的生命周期。当 Servlet 容器启动或终止 Web 应用时,会触发 ServletContextEvent 事件,该事件由 ServletContextListener 来处理。此外,ServletContextListener 接口还定义了两个方法,contextInitialized 和 contextDestroyed。通过方法名,我们可以看到这两个方法中一个是启动时候调用
(contextInitialized),一个是终止的时候调用 (contextDestroyed)。
类中通过 contextInitialized 方法初始化了一个 Jenkins 对象。在 Servlet 容器初始化的时候,Jenkins 对象会交由 WebAppMain 的 initTread 线程创建。