首先引用Wiki的介绍一下Hasor:

    “Hasor是一款开源框架。它是为了解决企业模块化开发中复杂性而创建的。Hasor遵循简单的依赖、单一职责,在开发多模块企业项目中更加有调理。然而Hasor的用途不仅仅限于多模块项目开发。从简单性、松耦合性的角度而言,任何Java应用都可以从中受益。Hasor与Struts,Hibernate等单层框架不同,它可以提供一个以统一、高效的、友好的方式构造整个应用程序。并且可以将这些单层框架建立起一个连贯的体系,可以说Hasor是一个搭建开发环境的框架。这一点与Spring比较相似,您可以理解Hasor可以作为Spring之外的一种选择。”

昨天忙乎到很晚终于确定了Hasor一个明确的启动过程。目前启动过程已经设计的比较清晰了,相比以前凌乱的设计显得优雅许多。接下来就是要对hasor做“手术”实现它们了,在这里首先将其设计思想介绍给大家。

主要结构:

在介绍Hasor生命周期之前先要说明的是在hasor中其主要的部分有三个:配置文件处理(Settings)、应用环境上下文(AppContext)、Guice3.0增强(ApiBinder)。在整个启动生命周期中上述三个部分可以使用的顺序是Settings->ApiBinder->Context。下面这张图罗列了Hasor核心接口功能和这三个部分的依赖关系:

上图中详细的罗列出Hasor的主要功能及其依赖关系。图中红色部分是Hasor的三个最基本部件,可以看出Settings、ApiBinder、AppContext三者是一个递进的关系。在Hasor启动生命周期中也是如此,当你可以使用ApiBinder时就意味着你此时不能使用AppContext,只能使用Setting相关功能。下面是各个部件的介绍。

Settings部件

Xml映射方式
    在Hasor中Settings接口主要负责配置文件的解析工作。Settings提供了一种统一的方式解析Xml,它会将Xml的所有数据按照Xpath的路径转变成为Key/Value键值对并以Map形式保存。例如Xml配置和映射关系如下:

<!-- 系统内置帐号信息 -->
<loginSafe enable="true">
<!-- 登陆表单递交位置 –>
<loginFormURL>/s_j_check</loginFormURL>
</loginSafe>
------------------------映射结果为------------------------
系统内置帐号信息
loginSafe = <XmlProperty类型对象> loginSafe元素的enable属性
loginSafe.enable= true 登陆表单递交位置
loginSafe.loginFormURL = /s_j_check

    注意1:当你的标签属性名和子元素名重名时Settings并不能有效的区分它们,此时你应当获得标签的 XmlProperty 接口使用DOM方式来获取你想要的东西。我不推荐将Xml标签的属性名和子标签使用相同名称。这样做会很容易混淆对Xml配置的理解。试想当你在看到一个标签有enable属性同时又看到子标签也叫 [ye'jz]有一个enable时,你一定不会第一时间知道哪个才是真正的启用禁用设置项。
    注意2:使用Key/Value键值对获取配置信息时Settings会忽略大小写敏感。在上面的例子中使用“loginsafe.enable” 或 “LOINGSAFE.ENABLE” 都可以获取到映射的属性值 “true”。

DOM方式操作配置文件
    在Hasor中使用Settings接口尝试获取的Xml配置项如果是一个标签元素那么可以采用getXmlProperty()方法获取XmlProperty接口对象,该接口对象提供XML的DOM操作。

ApiBinder部件

ApiBinder接口的设计初衷是负责提供模块启动过程中在AppContext尚未形成时的支持,这其中包含了Guice的Binder接口。用过Guice的朋友一定会熟悉Guice在Binder接口上提供了各种绑定的功能,当然这包括了定义Aop。详细有关Guice3.0的介绍您可以到Guice官方网站查看。Hasor不会直接提供给开发者Guice的Binder接口,不过开发者可以通过ApiBinder接口来获取Binder接口,这正式ApiBinder接口的作用之一。通过ApiBinder可以得到Settings及其相关部件的各种功能。此外注册Bean也是由ApiBinder提供。需要注意的是“ApiBinder接口仅仅在OnInit生命周期阶段有效”因为此时正在调用Guice.createInjector方法创建Injector对象,所以请不要将ApiBinder接口的引用保留到OnInit阶段之外,那样做是不安全的。

AppContext部件

AppContext接口负责支撑整个Hasor平台的运行,通过AppContext你可以轻松的管理当前系统的所有已加载模块,而且还可以像Spring一样通过服务名获取服务实例。AppContext提供了阶段性心跳事件(Timer)的支持。更多的AppContext信息请参看相关文档。

启动过程与模块生命周期

经过上面的介绍想必读者对Hasor的核心部件有了一定的了解。本文的最终目的是为了阐述Hasor的生命周期从启动到销毁各个阶段都做了什么、能做什么!那么下文正式开始阐述生命周期相关内容。右边的图展示了(Hasor生命周期、Hasor事件、模块生命周期)三者之间的关系。

  • load ns.prop 阶段(一)
        该阶段是创建Settings部件的必要过程,目的是为了Settings即将执行的Xml解析做准备。该阶段会读取classpath路径中所有“ns.prop”属性文件,并装载该文件中定义的Xml命名空间和对应的解析器汇总到一起注册到Hasor特有的Xml解析工具上。通过这个工具不同的命名空间解析器会收到属于它们命名空间下的Xml事件流。
    提示并虽然Hasor支持对每个模块都有可以有自己的Xml命名空间,但是我更建议使用不同的Xml标签作为模块配置内容的分界。
    (Hasor的Xml解析工具用的是Stax方式处理Xml并将解析结果转换为类似Sax的事件流,该工具可以将Xml事件流分割到不同的命名空间)
  • load Config.xml 阶段(二)
        该阶段是创建Settings部件的必要过程,主要目的是为了解析装载Xml配置文件。在Hasor中配置文件被分为两类:主配置文件(config.xml)和静态配置文件(static-config.xml)。Settings会在运行时监控config.xml配置文件的变化;并且自动重载变化的config.xml,而static-config.xml就不支持这种特性。在该阶段其具体处理过程分为如下三步:
        第一步:处理"static-config.xml"配置文件,使其生成一组Key/Value键值对(使用Map封装)。
        第二步:用同样的方式载入“config.xml”,但是与处理“static-config.xml不同的是处理“config.xml”不需要考虑classpath中存在多个“config.xml”的情况。并且将config.xml解析的最终结果合并并覆盖第一步产生的结果中。
        第三步:装载“config-mapping.properties”属性文件,该属性文件的作用是为某个Settings配置项目起一个别名。在配置文件升级时该功能可以有效的将老配置项移植到新版配置文件上。值得注意的是当起的别名和现有配置项目遇到冲突时,Settings会抛出一条警告,同时放弃这条记录的处理。
    提示:目前Hasor还不支持XSD验证功能。
  • do Start 阶段(三)
        这个阶段,会引发(OnInit、OnStart)两个事件。由这两个事件分别处理模块中对应的OnInit和OnStart生命周期方法。模块通过OnInit阶段可以利用ApiBinder接口在初始化阶段完成一系的绑定工作,而后当所有模块都初始化完毕之后在通过OnStart阶段完成后续操作。
  • Run 阶段(四)
        该阶段当所有模块都已经完成初始化并且启动之后进入该状态,在Run阶段Hasor会定时触发一次Timer事件。开发人员可以利用Timer处理一些应用程序运行中的小任务。开发人员可以通过ApiBinder或者注册AppEvent监听器来使用这个功能。
  • do Stop 阶段(五)
        通过调用stop或destroy方法可以引发该阶段的阶段性事件。OnStop事件会被传播到所有模块,用以通知模块停止服务的提供。此外start方法还可以将已经处于停止运行下的服务start方法重新启动。
  • do Destroy 阶段(六)
        destroy方法可以引发该阶段,该阶段标志着整个App应用被销毁。被销毁的应用程序不会接受再次启动。

生命周期状态转换

项目主页:https://github.com/zycgit/hasor
项目托管地址:https://github.com/zycgit/hasor
作者邮箱:zyc@hasor.net

Hasor:生命周期的更多相关文章

  1. react组件的生命周期

    写在前面: 阅读了多遍文章之后,自己总结了一个.一遍加强记忆,和日后回顾. 一.实例化(初始化) var Button = React.createClass({ getInitialState: f ...

  2. 浅谈 Fragment 生命周期

    版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Fragment 文中如有纰漏,欢迎大家留言指出. Fragment 是在 Android 3.0 中 ...

  3. C# MVC 5 - 生命周期(应用程序生命周期&请求生命周期)

    本文是根据网上的文章总结的. 1.介绍 本文讨论ASP.Net MVC框架MVC的请求生命周期. MVC有两个生命周期,一为应用程序生命周期,二为请求生命周期. 2.应用程序生命周期 应用程序生命周期 ...

  4. UIViewController生命周期-完整版

    一.UIViewController 的生命周期 下面带 (NSObject)的方法是NSObject提供的方法.其他的都是UIViewController 提供的方法. load   (NSObje ...

  5. angular2系列教程(十一)路由嵌套、路由生命周期、matrix URL notation

    今天我们要讲的是ng2的路由的第二部分,包括路由嵌套.路由生命周期等知识点. 例子 例子仍然是上节课的例子:

  6. Spring中Bean的作用域、生命周期

                                   Bean的作用域.生命周期 Bean的作用域 Spring 3中为Bean定义了5中作用域,分别为singleton(单例).protot ...

  7. Autofac - 生命周期

    实例生命周期决定在同一个服务的每个请求的实例是如何共享的. 当请求一个服务的时候,Autofac会返回一个单例 (single instance作用域), 一个新的对象 (per lifetime作用 ...

  8. 【微信小程序开发•系列文章六】生命周期和路由

    这篇文章理论的知识比较多一些,都是个人观点,描述有失妥当的地方希望读者指出. [微信小程序开发•系列文章一]入门 [微信小程序开发•系列文章二]视图层 [微信小程序开发•系列文章三]数据层 [微信小程 ...

  9. Xamarin.Android活动的生命周期

    一.前言 用过Android手机的人一定会发现一种现象,当你把一个应用置于后台后,一段时间之后在打开就会发现应用重新打开了,但是之前的相关的数据却没有丢失.可以看出app的“生命”是掌握在系统手上的, ...

随机推荐

  1. Caffe —— Deep learning in Practice

    因工作交接须要. 要将caffe用法及总体结构描写叙述清楚. 鉴于也有同学问过我相关内容, 决定在本文中写个简单的tutorial, 方便大家參考. 本文简单的讲几个事情: Caffe能做什么? 为什 ...

  2. 硬盘被误格式化或Ghost还原后的数据恢复

    硬盘格式化(Ghost还原)后的数据恢复 ---diskgenius使用之数据恢复 问题引出:计算机中病毒后用Ghost版本的winxp安装,由于安装途中选择了把映像安装到硬盘而不是分区,安装好后只剩 ...

  3. jsoncpp 不能处理long类型数据

    jsoncpp,是一个c++的解析和生成json的开源工具.假设你的c++程序须要解析或生成json,它会使这个过程变得非常easy! 可是,今天在用jsoncpp进行生成json的时候报了错误,非常 ...

  4. 在JDBC中使用PreparedStatement代替Statement,同时预防SQL注入

    本篇讲诉为何在JDBC操作数据库的过程中,要使用PreparedStatement对象来代替Statement对象. 在前面的JDBC学习中,对于Statement对象,我们已经知道是封装SQL语句并 ...

  5. 测试framebuffer

    static GGLContext *gr_context = 0; static GGLSurface gr_framebuffer[2]; static unsigned gr_active_fb ...

  6. 延迟函数 比sleep效果好

    sleep是会阻塞线程的 网上有些延迟函数测试下来还是会阻塞,而接下来推荐的代码则不会   1 2 3 4 5 6 7 8 9 procedure delay(dwMilliseconds:integ ...

  7. oracle 表连接 - hash join 哈希连接

    一. hash 连接(哈希连接)原理 指的是两个表连接时, 先利用两表中记录较少的表在内存中建立 hash 表, 然后扫描记录较多的表并探測 hash 表, 找出与 hash 表相匹配的行来得到结果集 ...

  8. rsync Backups for Windows

    Transfer your Windows Backups to an rsync server over SSH rsync.net provides cloud storage for offsi ...

  9. TMsgThread, TCommThread -- 在delphi线程中实现消息循环(105篇博客,好多研究消息的文章)

    在delphi线程中实现消息循环 在delphi线程中实现消息循环 Delphi的TThread类使用很方便,但是有时候我们需要在线程类中使用消息循环,delphi没有提供.   花了两天的事件研究了 ...

  10. Lucene.Net 2.3.1开发介绍 —— 二、分词(二)

    原文:Lucene.Net 2.3.1开发介绍 -- 二.分词(二) 1.2.分词的过程 1.2.1.分词器工作的过程 内置的分词器效果都不好,那怎么办?只能自己写了!在写之前当然是要先看看内置的分词 ...