为JBoss AS7添加新模块

9 篇文章 0 订阅
注:文本的内容主要探讨JBoss AS7的实现细节,涉及AS7的内核代码及分析,需要耗费大量时间与精力来学习理解。如果你只是基于JBoss进行应用开发或是日常运维管理,可以忽略本文,看看网站上其它和AS7使用及开发相关的内容。

在软件领域,模块化的设计思想变得越来越重要,它的目的是使得软件变得容易扩展。在这一方面,最典型的例子当属Linux内核:Linux Kernel通过模块化设计,允许开发人员撰写功能代码,并以驱动模块的方式加载进内核,使得系统扩展变得非常容易。JBoss AS7吸取了不少来自于操作系统方面的设计经验,通过"模块化"的设计,让开发人员可以通过搭积木的方式,向AS7中添加新的组件。

AS7有篇文档通过代码示例详细介绍了如何为AS7撰写新的模块,并加载进AS7核心:


https://docs.jboss.org/author/display/AS7/Extending+JBoss+AS+7


这篇文档中的语言比较简练,有些点说明的不够细致,因此撰写本文的[b]目的是针对这个例子做出一些补充说明帮助理解[/b],因此,将上面这篇文档和本文合起来阅读才是完整的。

首先,阅读上面这篇文档需要一些准备知识:AS7使用JBoss Modules来实现模块化的设计,在核心中依赖JBoss Modules进行模块的定义,加载,生命周期的管理。因此,首先需要理解JBoss Modules,可以参考下面这篇文档:


http://bluedash.net/spaces/JBoss%20Module介绍


如果你对AS7的基本使用还不熟悉,可以参考这篇文档:


http://bluedash.net/spaces/JBoss%20AS%207%20快速上手


这些准备工作做完后,就可以开始阅读 _Extending JBoss AS 7_ 。跟着文档里面的示例一步一步实验,到最后调通示例并对整体思路有个比较清楚的把握,大概需要10几个小时的时间,所以请准备出三、四天左右的时间来看这个示例。

我把一些原文中阐述不够详尽的地方,补充说明如下:

[b]示例说明及使用[/b]

[i]Extending JBoss AS 7[/i]中的示例的目的是为AS7制作一个记录已部署项目数量的模块。当这个模块加载进AS7以后,AS7的日志会定时输出系统中已部署的项目数量。AS7的日志输出类似如下:


12:04:24,935 INFO [stdout] (Thread-12) Current deployments deployed while war tracking active:
12:04:24,935 INFO [stdout] (Thread-12) [my-app.war]
12:04:24,935 INFO [stdout] (Thread-12) Cool: 0


这个模块的名字叫做Tracker。这个名字是在SubsystemExtension中定义的:


public class SubsystemExtension implements Extension {
...
public static final String SUBSYSTEM_NAME = "tracker";
}


整个模块的加载入口点为SubsystemExtension的initialize方法:


public class SubsystemExtension implements Extension {
...
@Override
public void initialize(ExtensionContext context) {
...
final ManagementResourceRegistration registration = subsystem.registerSubsystemModel(SubsystemProviders.SUBSYSTEM);
...
//Add the type child
ManagementResourceRegistration typeChild = registration.registerSubModel(PathElement.pathElement("type"), SubsystemProviders.TYPE_CHILD);
...
subsystem.registerXMLElementWriter(parser);
}
}


initialize中将模块中的各组件给装配到一起。两个ManagementResourceRegistration将组件注册进AS7;最后一行subsystem.registerXMLElementWriter(parser)负责tracker在AS7配置文件中配置内容的读取工作。以下是AS7中tracker相关的配置:


<extensions>
<extension module="com.acme.corp.tracker"/>
</extensions>

<profile>
<subsystem xmlns="urn:com.acme.corp.tracker:1.0">
<deployment-types>
<deployment-type suffix="sar" tick="10000"/>
<deployment-type suffix="war" tick="10000"/>
</deployment-types>
</subsystem>
</profile>


源代码中的parser就是负责将模块的配置转化成xml。Parser定义在SubsystemExtension中的SubsystemParser:


private static class SubsystemParser implements XMLStreamConstants, XMLElementReader<List<ModelNode>>, XMLElementWriter<SubsystemMarshallingContext> {

@Override
public void writeContent(XMLExtendedStreamWriter writer, SubsystemMarshallingContext context) throws XMLStreamException {
...
}

@Override
public void readElement(XMLExtendedStreamReader reader, List<ModelNode> list) throws XMLStreamException {
...
}
}


此外,在整个模块的加载入口点,SubsystemExtension的initialize方法中,注册了SubsystemAdd:


public class SubsystemExtension implements Extension {
...
@Override
public void initialize(ExtensionContext context) {
...
//We always need to add an 'add' operation
registration.registerOperationHandler(ADD, SubsystemAdd.INSTANCE, SubsystemProviders.SUBSYSTEM_ADD, false);
}
}


AS7内部定义了模块的生命周期,其中Add是指模块被添加时要做的事,因此SubsystemAdd就是在模块被添加进AS7内核时,要执行的工作:


class SubsystemAdd extends AbstractBoottimeAddStepHandler {
@Override
public void performBoottime(...) throws OperationFailedException {

processorTarget.addDeploymentProcessor(SubsystemDeploymentProcessor.PHASE, SubsystemDeploymentProcessor.PRIORITY, new SubsystemDeploymentProcessor());
}

}


注意到SubsystemAdd扩展的是AbstractBoottimeAddStepHandler,从名字就可以看出,AbstractBoottimeAddStepHandler的生命周期对应于模块启动时加载的这个环节。里面的performBoottime方法将将整个模块的主要功能,SubsystemDeploymentProcessor,添加进AS7内核。接下来我们可以看下SubsystemDeploymentProcessor:


public class SubsystemDeploymentProcessor implements DeploymentUnitProcessor {
@Override
public void deploy(...) throws DeploymentUnitProcessingException {
...
}

@Override
public void undeploy(...) {
...
}
}


SubsystemDeploymentProcessor实现的是DeploymentUnitProcessor,这是AS7提供的具多功能Processor模块当中的一种。开发者可根据自己的功能需要,选择不同的Processor来进行实现。这个DeploymentUnitProcessor从名字就可以看出,它是处理和工程部署有关的工作时,需要使用的Processor接口。

DeploymentUnitProcessor提供两个方法:deploy和undeploy,分别对应于当有新项目部署进AS7,或有既存项目从AS7中去除时,系统要做的事情。因此例子中的代码通过实现这两个方法,就完成了对AS7中部署项目的跟踪记录工作。

以上是整个例子的设计思路及脉络。如果要想完全理解这个例子中的全部细节,还需要拿出几天的时间来仔细阅读文档,并实际动手玩玩看这个例子。一旦掌握了AS7的模块化设计思路,你就可以慢慢体会体会到它的方便之处,并可以很方便地对AS7进行功能扩展和定制。

总的来讲,对AS7的模块开发,变得越来越像对Linux Kernel的驱动开发。理解了这种模块化的设计思路,对于自己架构应用时也很有助益。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值