首先引用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. 公钥password学中的素数以及对称加密

        password学.一向被人们觉得门槛非常高,特别高端...这也是实际,可是这决不意味着普通人无法了解它的精髓.对于喜欢画圆的人来讲,即便是理解了password技术背后的哪怕一点理论,也是激 ...

  2. 略懂 MySQL字符集

    本文虽说旨在明白.但若略懂亦可.毕竟诸葛孔明如是     只有基于字符的值才有所谓字符集的概念     某些字符集可能需要更多CPU.消费更多的内存和磁盘空间.甚至影响索引使用     这还不包括令人 ...

  3. Eclipse用法和技巧二:自动生成Main方法1

    刚开始编写java小程序,基本都要用到main方法.后期开发大一点的程序,也可以用main方法进行单元测试.总是编写main方法,感觉太无聊了,幸好Eclipse可以帮我们自动生成main方法.见图: ...

  4. C++基础学习笔记----第十四课(new和malloc的区别、单例模式等深入)

    本节主要讲new关键字和malloc函数的差别,编译器对构造函数调用的实质,单例模式的实现等. new和malloc的差别 1.malloc和free是C语言的库函数,以字节为单位申请堆空间.new和 ...

  5. 重操JS旧业第三弹:Array

    数组在任何编程语言中都是非常重要的,因为函数在最大程度上代表了要实现的功能,而数组则是这些函数所要操作的内存一部分. 1 构建数组 js与其他非脚本语言的灵活之处在于要实现一个目标它可能具有多种方式, ...

  6. QT学习小技巧

    原地址:http://blog.csdn.net/ykm0722/article/details/6947250 转载: 分享在比赛中写代码时,发现的几个对写程序很有用的小段代码,虽小但是在我的软件中 ...

  7. javascript 中 undefined 和 null 区别

    1.相同点 如果我们直接用 undefined == null  比较他们是相等的返回的将是 true. 2.区别 当我们用undefined === null 比较的时候最后返回的将是 false. ...

  8. 教会你如何编写makefile文件

    最近一直在学习makefile是如何编写的.当我们写的程序文件比较少的时候,敲入gcc /g++,当你在大型工程中,在一个个编译文件的话,你可能就会很郁闷.linux有一个自带的make命令,它让你的 ...

  9. ASP.NET - 跳转页面

    1. Response.Redirect("../Manager/AddBookInfoImages.aspx?id=" + Server.UrlEncode(ReturnValu ...

  10. 批处理运行python

    @echo off cd C:\test start python test.py start python test2.py exit