dev@glassfish.java.net

Introducation Of Jmin service

From: chris <liao.jiajun_at_sz-excel.com>
Date: Fri, 16 Mar 2007 09:18:59 +0800

各位大师,前辈,


您们好!

我叫Chris Liao,是一名Java爱好者,目前生活在中国深圳.很抱歉,由于个人英语能力有限,所以这封邮件采用了中文表达. 目前本人正在学习J2ee技术,并有了一些设想,但不知道是否可行,
所以想请各位专家给予指点,由于渴望进步,才冒昧发这封中文邮件.如果您不熟悉中文,我在这里郑重向您表达歉意!(If you are not familiar with Chinese, I think i should make
apology to you !).文档如下:



Jmin service


1. 介绍... 1

1.1 什么是服务?. 1

1.2 服务与客户端... 2

1.3 服务与域驱动... 2

1.4 服务与生命周期... 2

1.5 服务与服务之间... 3

1.6 服务与组合... 3

1.7 服务与组件... 3

1.8 组件与容器... 3

1.9 组件与描述... 3

1.10 组件与部署... 4

1.11 组件源与发现机制... 4

1.12 服务与助手... 4

1.13 组件源与辨别... 4

1.14 组件源与解析... 5

2. 应用探讨... 5

2.1 应用目标: 5

2.2 探讨范围: 5

2.3 J2EE服务... 5

2.4 服务层次与关系... 5

2.5 服务的配置... 6

2.5: 服务的装载... 6

2.6: 服务的部署... 6

2.7 微内核控制发现... 7

2.8 微内核控制部署... 7

2.9 组件的容器... 8

2.10服务的容器... 9





1. 介绍

Jmin service是一个面向服务域编程(SOP)的架构,被包含在Jmin服务器中.如果您对该架构不熟悉的话,那么下面我们将介绍一些它所涉及到的基本概念.



1.1 什么是服务?



我们为什么要访问服务器呢? 望文生意,那是因为服务器能够提供一些有意义的应用供客端访问,并且这些应用能够处理来自客户的请求,这一现象普遍存在于客户端/服务器模式.在工作与学习中,可能我们每天都在使用或享用这样或那样的应用,尽管有时,它们看上去非常复杂与异样,但是如果细心研究它们,也许我们可以发现一个共同点:每个应用表达某个方面的观点或解决某个方面的问题,并对它的外界产生影响,如:处理来自外部的调用或者完成一些有意义的任务.我们建议用“服务” 这个词表这些具有共同点的应用. “服务” 是一个逻辑概念,在
它的活动范围内,一些其他对象可能会集成到一起去完成某些协作,这些对象可以是逻辑集成,物理分离的.尽管有时 “服务” 这一词没有出现在某些应用中, 但事实上它们是有可能在做类
似概念的工作. 我们已经把 “服务” 一词抽象成一个接口了,并定义在我们的框架规范中.



1.2 服务与客户端



如果可供访问的服务是存在的,那么客户端是有可能访问到它们.当然一些服务对客户端是不可见的,因而是无法被客户端访问,例如: 我们定义一个内部服务,主要负责装载一些作用于其他服务的参数
. 所以服务的存在不一定是为外部调用,服务具体行为依赖于它所属的问题域,拓展者可以自由决定它们的具体行为.





1.3 服务与域驱动



一般来说,服务是用来处理或映射某个方面或某些方面的问题与观点.换句话说,每个服务可一匹配到某个或某些方面,我们把这个方面定性为域(Domain).服务的具体定义依赖于域的问题.事实上,我们可以称成服务为逻辑方面域,但这点与纵切面AOP的 ”方面”一
词,是有区别的.



1.4 服务与生命周期



不同服务,它们的周期有可能会不一样,比如有些是完成某些事情之后就结束了,但也有一些,可能一直伴随系统的而存在的. 关于服务何时创建,何时死亡,我们没有定性,拓展者可以自由决定它
们.



1.5 服务与服务之间



既然服务被用来处理域问题的,那么从服务的外部角度来看,它是有可能被其他服务所调用,所以服务之间是很有可能存在依赖关系.





1.6 服务与组合



服务是可以组合在一起,形成更大范围的服务.







1.7 服务与组件



通常情况下,服务并不孤立存在的,我们可以让一些组件运行在它们之上,并使之成为服务的组成部分.在软件业中,服务与组件的技术目前非常流行:开发员可以设计并开发他们自己的组件去完成某些业务操作的。仔细观察,这些组件还是可以划分到某些域中去,我们认为这就是服务域.当我们调用这些组件的接口,事实上我们隐式使用它们所匹配的域服务.服务的概念是抽象的,不容易捕获,当然没有组件的服务也是可行的,这点完全决定于拓展者的意图。





1.8 组件与容器



服务是如何持有组件的呢?容器被期盼用来管理组件的,例如池化和生命周期等。但是容器是如何感知组件的呢?我们觉得应该提供一种描述手段来让容器感知组件.我们定义了一个基本容器接口(Container. java),当然拓展者也可以利用
它存储其他对象.







1.9 组件与描述



在当前普遍的情况下,我们使用物理文件去存储组件和它们的描述,而这些描述可能是XML文件,也可能是properties 文件,还可能是EJB3.0所才采用的Annotation等等,不管采用何种方式描述
组件,它们都属于描述的范畴。我们可以描述组件的名字,事物,安全等。组件一旦被需要装载到系统中,那么这些描述将发挥至关重要的作用。由于描述方式存在多样性,所以我们在我们的框架中采用对象描述对象方式,并定义了一个基本描述接口(Desc.java). 在程序
运行时,我们只需要将其他描述方式转化为该方式即可. 我们认为这点是可行的.但是如何利用它描述对象呢? 它的内部结构又是如何? 完全决定于拓展者. 尽管描述是一种好手段,但毕
竟有存储位置,我们把位置称为源(Source.java)









1.10 组件与部署

组件不会无缘无故跑进了服务的容器中的,可能是我们利用代码装载组件的,也有可能是我们将包含组件源布署到某个指定的位置,这样服务才会装载这些外部的组件.在访问组件之前,它们应该是已经被装载了,至少是组件的描述信息已经存在. 由于有各种
各样的服务,那么服务布署组件过程可能会存在差异. 当布署组件时,组件描述应该是非常重要的.很多时候, 我们可以把布署看成是组件的开始,很多其他事情都是包含在它的。





1.11 组件源与发现机制



一旦组件源被部署到制定位置,那么我们应该提供一种机制去发现这些部署的组件源。例如:部署,重部署.一旦发现,那么该机制应该存在一种通知手段去通知部署控制器,这样控制器就可以决定部署的Happy-path. 在我们的框架中,我们定义一
个发现者(Discover)去发现组件源,

一旦发现,发现者将发布一个发现Event, 发现Listener去监听这些Event.





1.12 服务与助手



我们定义了一个助手基本接口(Assistant)去帮助服务完成某些事情,具体行为由拓展者决定







1.13 组件源与辨别

由于服务的差异, 对于它们的组件描述可能存在差异, 那么将组件源部署进服务时,是如何为这组件源找到匹配的服务去装载解析它们呢?一旦发现组件源,那么应该召集所有可以部署组件的服务来辨认这些source.如果匹配的话,那么该服务将应用这个组件源. 我们
定义了一个辨别器(Discriminator)在框架中,该接口决定了组件源是去上哪个服务.该辨别器接口是对服务助手接口的扩展.







1.14 组件源与解析



当组件源应用到服务上时,它们应该被解析:比如获取组件描述.我们定义了一个基本口:Parser去做这方面的事情。该辨别器接口是对服务助手接口的扩展.









附:Jmin service是由一些没有定性的规范接口构成。





2. 应用探讨



2.1 应用目标:

1: 对Jmin service进行扩展, 形成一个微内核框架

2: 在该微内核框架之上,尝试去组织一个简单的Server(Jmin)


2.2 探讨范围:

1: 组织结构

2: 部署控制

3: 容器探讨



2.3 J2EE服务



在J2EE Server上,有许多应用的存在,如EJB, JDBC, Name, Transaction等. 我们仔细分辨一下,它们是不是面向某个领域的? 对照上面的介绍,是不是可以用介绍中的服务概念来抽象描述它们
呢? 我们就可以为这些J2ee域 建立响应的服务,如: EJB服务, JDBC服务,命名服务等.面对如此多的J2ee服务,我们是不是可以配置这些服务呢? 服务器上的服务是不是可以有选择性进行组织呢? 如何控制
它们呢? 我们设计一个J2ee微内核框架正是回答这些问题的.





2.4 服务层次与关系

我们将服务按级别区分为多个层次

1:核心层(接口层)

2:扩展核心层(接口层)

3:中心服务层, 包含一个中心服务,它控制那些控制层的服务,

4:控制服务层, 包含一个发现器,和一个超级服务,管理那些应用层的服务.

5:应用服务层, 包含许多应用的服务,如: POJO,EJB等.

6:组件层: 应用层的组件



饼图如下:







2.5 服务的配置

控制层的服务与应用层的服务都配置在相应的XML文件中:control.xml 和 service.xml

而且服务的配置是有先后次序.因为服务之间和有可能存在依赖关系!



2.5: 服务的装载



一旦启动微内核,那么它将开始实例话中心服务,启动中心服务,那么中心服务将会读去XML配置文件,然后解析配置文件,并将每个控制服务的描述都注册到容器中去.



2.6: 服务的部署



1:中心控制服务的部署

        中心服务在注册完所有控制服务描述后,开始实例化刚注册的服务,并使他们跑起来.



2:应用层服务的部署

   控制层的超级服务将会部署那些外来的服务,原理同上.





2.7 微内核控制发现

我们在控制服务层放置了一个发现者服务,我们利用它去发现那些部署的组件源,一旦发现,将发出Event 通知, 发现监听器将会收到该事件,并且召集所有可以部组件的署服务来辨别这
个组件源,一旦识别将进行相应的应用,如:部署,反部署.



while (itor.hasNext()) {

      J2eeService service = (J2eeService) itor.next();

      if(!(service instanceof J2eeAbstractService)){

        continue;

      }



      J2eeAbstractService j2eeService = (J2eeAbstractService)service;



      J2eeDeployAssistant assistant = j2eeService.getAssistant();

      J2eeComponentDiscriminator discriminator = j2eeService

          .getDiscriminator();



      if (assistant == null || discriminator == null)

        continue;





        if (discriminator.identify(event.getEventSource())) {



          /**

           * Means that the source contained in the event has found a
matched service.

           * The assistant of the matched service will do some operation on
it.

           */

          isAcceptable = true;

          if (event instanceof J2eeDiscoverDeployEvent)

            assistant.deploy((J2eeSource)event.getEventSource());

          else if (event instanceof J2eeDiscoverUndeployEvent)

            assistant.undeploy((J2eeSource)event.getEventSource());

 }





2.8 微内核控制部署

可以部署组件的服务,都应该有自己的识别器与部署助手,



public interface J2eeDeployAssistant extends J2eeyAssistant {



  public void deploy(J2eeSource source) throws J2eeDeployException;



  public void undeploy(J2eeSource source) throws J2eeUndeployException;



}



2.9 组件的容器



我们定义了一系列容组件器类



容器1: J2eeComponentIocContainer.java

…………………

 public Object registerComponentDesc(J2eeComponentDesc desc)

      throws J2eeRegistrationException;



 public void unregisterComponentDesc(Object key)

      throws J2eeUnRegistrationException;



 public Object getComponent(Object key); // Why not be Component ???



………………………………………………



特点:

将组件的描述注册到容器中,然后再去获取组件实例. 与IOC是不是有相似之处?

其实我们觉得IOC 容器在注册类时,也是将bean描述告知容器,应该算是描述的范畴.



容器2: J2eeApplySourceContainer.java



  public synchronized void applyJ2eeSource(J2eeSource source, int flag)

      throws Exception {



    logger.debug("Container apply source: " + source);



    switch (flag) {

      case J2eeDeploymentFlag.DEPLOY: {

        this.deploySource(source);

          break;}



        case J2eeDeploymentFlag.UNDEPLOY: {

          this.undeploySource(source);

            break;}



          default:

            break;

    }

  }



 public abstract void deploySource(J2eeSource source) throws Exception;



public abstract void undeploySource(J2eeSource source) throws Exception;



特点:

将组件源直接应用到容器中,具体过程有子类实现,一旦部署成功,容器将记住该source.的一个标志,为什么呢?



2.10服务的容器

我们已经把J2ee服务继承了组件接口,因此服务是可以象组件一样部署上去,已经实现一个服务的容器.







更多信息请阅读源码,地址:http://jmin.dev. java.net





Chris liao



2007/03/15





附:该作品的设计理念及代码的所有权归Jmin 组织所有,任何公司,组织,个人未经许可,禁止拷贝该设计,违者必究











clip_image001.gif
(image/gif attachment: clip_image001.gif)

clip_image002.gif
(image/gif attachment: clip_image002.gif)

clip_image003.gif
(image/gif attachment: clip_image003.gif)

clip_image004.gif
(image/gif attachment: clip_image004.gif)

clip_image005.gif
(image/gif attachment: clip_image005.gif)

clip_image006.gif
(image/gif attachment: clip_image006.gif)

clip_image007.gif
(image/gif attachment: clip_image007.gif)

clip_image008.gif
(image/gif attachment: clip_image008.gif)

clip_image010.jpg
(image/jpeg attachment: clip_image010.jpg)