Hasor 同 Spring OSGi 的比较及设计思想
Hasor 同 Spring OSGi 的比较及设计思想
哈库纳 发表于4年前
Hasor 同 Spring OSGi 的比较及设计思想
  • 发表于 4年前
  • 阅读 4253
  • 收藏 83
  • 点赞 10
  • 评论 27

新睿云服务器60天免费使用,快来体验!>>>   

    这篇是承接《轻量级 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 的轻量化框架。利用它你可以搭建自己的框架,利用它你可以整合诸多技术。

  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
哈库纳
粉丝 934
博文 81
码字总数 149803
作品 4
评论 (27)
ForJustice
最近博主好活跃,支持一下
YANGL
非常棒, 微内核+插件扩展
哈库纳

引用来自“YANGL”的评论

非常棒, 微内核+插件扩展

没错,hasor 就是这种思路。 而且它不局限在单一的环境里。
推荐你关注一下hasor~~
哈库纳

引用来自“ForJustice”的评论

最近博主好活跃,支持一下

谢谢你的支持
淘淘我的小宝宝
持续关注中
java10001
关注一下,有机会实战一把
哈库纳

引用来自“java10001”的评论

关注一下,有机会实战一把

接下来把多数据源事务问题解决了之后,hasor就可以正式投入使用了。
事务这块我还是想把它做成想spring 那样可以支持多种传播方式。

非常感谢关注 hasor
dukerr
java模块化的水很深。
山哥
其实我一直在纳闷:控制反转,依赖注入有那么重要吗?它们所带来的松耦合等特性在企业开发中又有多少的必要性? 一个产品开发完后,以后的功能扩展等又有多少使用了这些特性? 越来越感觉其越来越是个嚼头,越简单的开发越好,抛弃所有的s2sh等框架吧。
哈库纳

引用来自“山哥”的评论

其实我一直在纳闷:控制反转,依赖注入有那么重要吗?它们所带来的松耦合等特性在企业开发中又有多少的必要性? 一个产品开发完后,以后的功能扩展等又有多少使用了这些特性? 越来越感觉其越来越是个嚼头,越简单的开发越好,抛弃所有的s2sh等框架吧。

单说控制反转,依赖注入。本身我觉得重要性并不是很大。
但是所带来的松耦合思想却是非常经典的,而松耦合我觉得必须配合面向接口编程才可以达到效果。
你可能感觉这样更麻烦了。

但其实不是,通常我们觉得软件开发完了就完事了。可是一个软件的生命周期远比开发周期长的很多很多。

软件在开发完成之后会一直持续在维护期直到没有人在使用它为止,在这期间软件需要一直维护。我觉得作为一个有责任的开发者应该充分考虑到软件维护期带来的成本。

松耦合有一个好处它可以让软件程序从一个整体变成各类零件,维护一个汽车零件要比维护一整个汽车要简单的多。更何况研发团队的人员并不是一成不变的,后来者可能根本不知道为什么软件是这么设计的。

而面向接口可以让松耦合更加稳定。

比如说,在维护期一个改掉了一个类,而这个类在软件若干位置都有引用,那么势必这些地方都要一起修改。虽然很可能软件改动只是在构造方法里增加了一个非空判断。但是天知道,是否就有地方用了这个特性。而测试人员面对这样的情况只好将软件整个测试一遍,这种代价非常昂贵。如果软件比较大,每次修改 Bug 的成本甚至会超过研发成本。

为了避免牵一发动全身软件开发中普遍使用的概念就是模块化、松耦合、面向接口。
哈库纳

引用来自“山哥”的评论

其实我一直在纳闷:控制反转,依赖注入有那么重要吗?它们所带来的松耦合等特性在企业开发中又有多少的必要性? 一个产品开发完后,以后的功能扩展等又有多少使用了这些特性? 越来越感觉其越来越是个嚼头,越简单的开发越好,抛弃所有的s2sh等框架吧。

:控制反转,依赖注入,还有 AOP 都是为了降低维护成本而形成的设计思想。 new 虽然很简单但是面临的问题很多。 即便是现在 IoC/Aop 依然有很多问题需要面对。
---_I_---
支持,楼主 ,一直在关注楼主这个项目,!
哈库纳

引用来自“抓瓦工人”的评论

支持,楼主 ,一直在关注楼主这个项目,!

谢谢你的关注。
就在刚刚 JDBC 增加了保存点功能。预计不久的将来 Spring 那套嵌套事务机制可以搬到 Hasor 上来了。
北方羊

引用来自“dukerr”的评论

java模块化的水很深。

确实。clone下看看。。
---_I_---

引用来自“哈库纳”的评论

引用来自“抓瓦工人”的评论

支持,楼主 ,一直在关注楼主这个项目,!

谢谢你的关注。
就在刚刚 JDBC 增加了保存点功能。预计不久的将来 Spring 那套嵌套事务机制可以搬到 Hasor 上来了。

真勤奋,我一直也想用guice做个框架,看了楼主这个设想,我觉得和我的想法很相似而且比我的更全面,哈哈,
其实我的设想模块是基于每个app的,,现在很多app就像struts2 一样,一个核心可以提供很多接口,用户如果需要新的功能可以基于struts2的核心开发插件,这样,每个app就围绕一个核心来开发了,其实每个app就是核心的一个插件,这么做的考虑有这些,1 所有系统通用的模块可以一次性开发,放在更高层次,下面app调用,比如文件上传,如果位于核心,每个插件就可以直接调,而不必重复部署,还比如安全模块,目前基于 spring security的 配置,如果有多个项目需要安全模块,还是需要多处配置,如果安全检查也位于上层,下面只是调用,传入参数,这样的话可以大幅度减少重复部署,我的想法还不成熟,希望能与楼主交流!
哈库纳

引用来自“抓瓦工人”的评论

引用来自“哈库纳”的评论

引用来自“抓瓦工人”的评论

支持,楼主 ,一直在关注楼主这个项目,!

谢谢你的关注。
就在刚刚 JDBC 增加了保存点功能。预计不久的将来 Spring 那套嵌套事务机制可以搬到 Hasor 上来了。

真勤奋,我一直也想用guice做个框架,看了楼主这个设想,我觉得和我的想法很相似而且比我的更全面,哈哈,
其实我的设想模块是基于每个app的,,现在很多app就像struts2 一样,一个核心可以提供很多接口,用户如果需要新的功能可以基于struts2的核心开发插件,这样,每个app就围绕一个核心来开发了,其实每个app就是核心的一个插件,这么做的考虑有这些,1 所有系统通用的模块可以一次性开发,放在更高层次,下面app调用,比如文件上传,如果位于核心,每个插件就可以直接调,而不必重复部署,还比如安全模块,目前基于 spring security的 配置,如果有多个项目需要安全模块,还是需要多处配置,如果安全检查也位于上层,下面只是调用,传入参数,这样的话可以大幅度减少重复部署,我的想法还不成熟,希望能与楼主交流!

哈哈,太巧了,你的这个想法我去年差点动手去实现它。基于一个运行平台下的 APP 框架,这个设计思想很有潜力。

去年我的想法和你一样,现在我觉得这有点相当于制订一款 Tomcat 或者 Jetty。感觉比较局限而且部署时候由于容器已经确定了反而降低了它的实际部署兼容性。

就在刚刚看到你这条评论时我觉得,如果设计的这个容器可以支持自动分布式部署在配合负载均衡。可以实现更大的目标,有点像百度的 BAE 只不过是浓缩的 Java 版。
魔眼神心

引用来自“哈库纳”的评论

引用来自“山哥”的评论

其实我一直在纳闷:控制反转,依赖注入有那么重要吗?它们所带来的松耦合等特性在企业开发中又有多少的必要性? 一个产品开发完后,以后的功能扩展等又有多少使用了这些特性? 越来越感觉其越来越是个嚼头,越简单的开发越好,抛弃所有的s2sh等框架吧。

单说控制反转,依赖注入。本身我觉得重要性并不是很大。
但是所带来的松耦合思想却是非常经典的,而松耦合我觉得必须配合面向接口编程才可以达到效果。
你可能感觉这样更麻烦了。

但其实不是,通常我们觉得软件开发完了就完事了。可是一个软件的生命周期远比开发周期长的很多很多。

软件在开发完成之后会一直持续在维护期直到没有人在使用它为止,在这期间软件需要一直维护。我觉得作为一个有责任的开发者应该充分考虑到软件维护期带来的成本。

松耦合有一个好处它可以让软件程序从一个整体变成各类零件,维护一个汽车零件要比维护一整个汽车要简单的多。更何况研发团队的人员并不是一成不变的,后来者可能根本不知道为什么软件是这么设计的。

而面向接口可以让松耦合更加稳定。

比如说,在维护期一个改掉了一个类,而这个类在软件若干位置都有引用,那么势必这些地方都要一起修改。虽然很可能软件改动只是在构造方法里增加了一个非空判断。但是天知道,是否就有地方用了这个特性。而测试人员面对这样的情况只好将软件整个测试一遍,这种代价非常昂贵。如果软件比较大,每次修改 Bug 的成本甚至会超过研发成本。

为了避免牵一发动全身软件开发中普遍使用的概念就是模块化、松耦合、面向接口。

嗯,同感1024
魔眼神心
很喜欢这种context + 插件扩展思想,公司一直有人在做面向积木编程,也是类似的思想,关注hasor的发展~
哈库纳

引用来自“魔眼神心”的评论

很喜欢这种context + 插件扩展思想,公司一直有人在做面向积木编程,也是类似的思想,关注hasor的发展~

谢谢关注,最近 Hasor 正在努力完善 JDBC 事务管理方面的缺陷。
不会飞的猪
mark~
×
哈库纳
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: