这篇是承接《轻量级 Java 开发框架 设计》系列Blog文的后续文章,本文将通过设计思想,实现方式上对比 Hasor Spring OSGi 三者。
在开启本文之前我想用最简短的一段话介绍一下 Hasor 。
Hasor 它是一个 Java 应用开发框架,可以说任何类型 Java 项目都可以使用 Hasor 进行开发。 它的设计思想是通过为 Guice 构建了一个 Context 环境,并且配备了一套完善的插件扩展接口。剩下的所有功能都是由插件完成。
很多朋友当看完上面这段介绍之后,脑海里便浮出 OSGi。
当 Hasor 第一次登台 OSC 是通过一篇有关模块化开发的文章开始,在一开始便有人将 Hasor 与 OSGi 进行了对比。于是也有人觉得 Hasor 绝不会是轻量级的。
况且 OSGi 是企业级模块化标准之一,而恰恰 Hasor 的首次亮相也是通过模块化概念进行阐述。这也难怪 Hasor 从一开始就和 OSGi 有着解不开的关系。
直到我加入一个小组讨论中才发现,将 Hasor 看作是 OSGi 翻版的人并不是少数。虽然我已经极力的介绍过它的架构和一些功能设计。但是很多朋友依然还认为 Hasor 和 OSGi 比较相似。
在设计 Hasor 之前我也研究过 OSGi ,其实从本质上 Hasor 和 OSGi 是根本不同的两个东西。
我个人觉得,Hasor 的架构思想和 Spring 是基本一样的,都是在依赖注入控制反转基础上建立起的框架体系。而 Hasor 不同于 Spring 的是 Hasor 更注重插件接口,这样的设计其实是最小化 Hasor 的重要保证。
因为我们知道现在的 Spring 已经不是几年前的 Spring ,它的功能逐渐变大增强,或许有些人认为 Spring 在某些领域已经不能被称之为轻量级了。我猜想这最主要的原因是项目依赖的 Jar 包太多了,动不动就几十上百兆。
Hasor 在初期注重插件接口,在这一部分 Hasor 走在 Spring 前面。也正是通过这种方式 Hasor 才可以保证在将来功能增长时可以保证孑然一身,最轻化。
即使是现在 Hasor 具备了三大模块,共计 14 个插件,累计 524 个类文件的时候,真正属于 Hasor 的核心部件仍然只有最初的 45 个类文件。在包括注释在内平均每个类文件不会超过 400 行。其余所有类都是 Hasor 的插件,而插件是可以被抛弃的。即使是未来的功能增长能促使 Hasor 更新核心类的地方也很难出现。
因此我可以肯定的说 Hasor 本身是轻量级的!它绝不重!
--------------------------------------------------------------
1.OSGi 是一个插件平台
OSGi 了解它的朋友都知道,OSGi 有着一个完善的模块化插件体系。OSGi 会为每个插件单独分配一个独立的 ClassLoader,并且 OSGi 还为每个插件提供了动态装载,卸载以及热部署的支持。
如果你了解的更多会发现 OSGi 甚至可以从你指定的 URL 地址中自动更新插件版本。而且它还可以处理模块多种版本同时存在情况下的兼容问题。如果这还不算什么的话,OSGi 还会带给你更多惊喜。
2.OSGi 是一个服务平台
在 OSGi 中每个插件都可以通过容器提供的接口向外发布服务。同时插件也可以使用其它插件发布的服务。而这一切都是通过 OSGi 连接点完成。
OSGi 连接点的使用是插件与插件之间沟通的主要媒介,这一点在使用上有点类似“依赖注入”,不同于传统依赖注入的是 OSGi 当注入一个服务对象时候都会为这个服务对象包装一个代理层。正是有了这层代理层 OSGi 才可以完成热更新。同样,借助这层代理 OSGi 也提供了相同插件不同版本共存。
3.OSGi 是一个工业级的标准
如果你对 OSGi 还有一点不清楚的话,我告诉你它是一个工业化的标准,一个真真正正的模块化开发框架。它的模块化体现到了方方面面。
你可以不用理会你的插件是否会引发 OSGi 容器运行的不稳定,也不用担心其它插件会影响到你程序的运行。而这一切正式通过 OSGi 完善的版本号管理来提供的。
正因为如此你可以在 OSGi 标准上同时让一万个人同时开发不同的插件,最后可以稳定的集成到一起。而这一切如果不是工业化的标准恐怕是很难实现的。也正因为如此 OSGi 给人感觉太重了。
4.OSGi 与 Hasor 对比
如果说 Hasor 还有资格和 OSGi 对比的话,我只能说 Hasor 也有插件。Hasor 通过扩展插件来扩充自己的功能。而这一切,只是建立在所有插件都要求实现 Module 接口的前提下。
Hasor 也提供了模块的依赖,这似乎让 Hasor 更加接近 OSGi 。可是 Hasor 模块依赖管理,其本质只是为所有插件提供一个初始化先后顺序的配置方式。所以在一开始 Hasor 与 OSGi 就有着本质的差别。
OSGi 会为每个插件提供一个独立的 ClassLoader 。而 Hasor 要求所有插件类都必须可以在同一个 ClassLoader 下找到。即使 Hasor 的插件支持 独立 ClassLoader 这个功能恐怕也只能由一个 Hasor 插件在其插件上提供的“插件功能”。
5.Spring 与 Hasor 的相似
轻量化 Java 开发框架 Spring 我觉得它绝对算得上轻量化,即使是现在我也认为 Spring 依然是轻量化框架中的娇娇者。
Hasor 与 Spring 从天生就注定很像,因为 Hasor 与 Spring 的核心思想是一样的。都是基于依赖注入和控制反转来构建整个架构。它们俩都通过 Context 为整个应用程序构建基础运行环境,也都是在 Context 上通过 IoC/Aop 为应用程序提供基础支持。
6.Hasor 是基于注解开发,而非 Xml
Hasor 与 Spring 不同的是 Spring 紧紧环抱 Xml 配置文件。而 Hasor 则主要基于注解开发。在一般情况下,使用 Hasor 开发应用程序不需要编写任何配置文件,它是绝对零配置的。
不过当你例如需要连接数据库或者修改默认配置。也只好通过 Hasor 的配置文件进行配置了。除此之外您不需要通过配置文件注册 Bean、Action、事务等等开发性的东西。
Hasor 的配置文件主要是留给业务系统的,我们往往在开发一个程序时经常会产生一些配置信息。一般情况下我们使用属性文件去承载,这是由于解析自定义 Xml 配置文件实在是繁琐且必要性不大。Hasor 提供了一种统一的方式读取自定义配置文件。
这种方式使得开发者可以拥有 Xml 那种结构化的表述,同时还保留了属性文件那种简单方便的特性。您可以不编写任何代码直接从一个自定义配置文件中读取到配置信息。而它的读取方式却和读取属性文件一样。
我猜想,实施人员会很喜欢这个特性。因为结构化的Xml 总比若干属性文件来的更加直观。即使是开发人员,也会从中得到很多快乐。
7.Hasor 小,轻,快
Hasor 与 Spring 一样是一款轻量化框架,它甚至比 Spring 更加轻量。这一点不单单是从 Jar 包体积上体现。
在 Hasor 中没有 Spring 那种庞大的配置文件映射解析系统。我曾经尝试开发一个与 Spring 相似的配置文件解析映射系统,当我完成了 300 个类规模的时候。我仅仅做到了Spring Beans、Spring Context两个组成部分的解析。在 Hasor 中有关配置文件解析的类文件只有 12 个类文件。代码总行数不过 1000 行,而这其中包括了 import 等元素。
Hasor 没有开发 IoC.Aop 部分,这一部分转而是由 Google 公司出品的 Guice 工具提供。Guice 是一款轻量化 DI 工具。这个工具可以说只是 JSR-330 的一个标准实现,除此之外 Guice 别无它用。
单单一个 Guice 是无法和 Spring 抗衡的,开发者如果想使用 Guice 去代替 Spring。也需要做很多工作之后才能完成迁移。这些工作当然不仅仅是代码上的改动。这主要是由于 Guice 本身缺少了 Spring Context 部分,而 Hasor 恰恰是在补充 Guice 确实的那部分。
在 Guice 官网上我们可以看到 Guice 号称快过 Spring 1000 倍。我想这个数据差异应该不仅仅是启动速度的体现把。
Guice 在对 Bean进行依赖注入时不会预先的知道都需要哪些属性需要注入,在它内部 Guice 使用了经典的 Visitor 模式当遇到 @Inject 时候才去构建依赖注入的对象。这种设计会比 Spring 从其内部庞大的 Bean 定义元信息中解析数据来的更加直接,更加迅速。同样的 Guice 也不需要通过容器管理 Bean 的生命周期,这也为创建 Bean 提供了大量宝贵的性能。
8.Hasor 设计思想
Hasor 坚持走轻量化路线,努力的保持其核心最小化。这个目标和 JFinal 有些接近。但是当 Hasor 要想保持自己轻盈,又想壮大功能时。免不了会与目标发生冲突,毕竟支持一个功能最起码也是需要经过编码的。这是一个瓶颈,也可以说是一个软件的设计边界。
许多开源软件最终都走到这一边界停下了自己的脚步,Hasor 试图踏出这一边界。所以 Hasor 最核心的问题是如何面对这个瓶颈。
OSGi 的插件体系的确给了 Hasor 一些灵感。作为 OSGi 最成功的项目 Eclipse 而言,整个Eclipse 都是由插件堆砌起来的如果将 Eclipse 中所有插件全部剔除,您会发现这只能剩下一个 OSGi Context 程序。
正是这个灵感,才促使 Hasor 有了一个突破口。
假如 Hasor 的核心功能是 @Aop、@Event、@Controller、@Restful、@NeedCache、@Power.... 谁会晓得哪里是个头呢?
一味的集成最后只能让 Hasor 走到轻量化框架的边缘,然后制住脚步等待后来者,最后与后来者一同埋葬在轻量化框架的坟场中。
因此 Hasor 也采用 Context + Plugin 这种模式。重点放在 Plugin 接口如何设计而非 @Aop @Bean @Controller 的设计。
Hasor 认为,插件是灵活的并且极不可靠。永远都有更加有效的 @Controller 来替代已存在的。因此 Hasor 当遇到 Web 时只会通过设计为其提供一个 Web 下的插件开发接口。这样一来所有 @Controller @Restful @Hessian @WebService @WebServlet @WebFilter 都可以插件形式在 Hasor 上运行。
插件本身又不属于 Hasor 有了这样的保证,Hasor 才可以放心大胆的去走出瓶颈,突破轻量化框架的边界。而这一切到目前为止还很有成效。
Hasor 目前包含了 Hasor-Core、Hasor-Web、Hasor-JDBC 三个部分,共计 14个插件,插件的数量仍在上升 Hasor 通过插件扩充自己的领域。也通过插件为开发者提供更加友好的开发体验。
假如开发者不喜欢 Hasor 的 @Controller 开发者完全可以自己开发一个全新的将其取之。而 Hasor 本身却不会受到任何影响。
这就是 Hasor ,一个基于 Guice 的轻量化框架。利用它你可以搭建自己的框架,利用它你可以整合诸多技术。