介绍 Spring JMXSpring 1.2 中的 JMX 支持使用容易配置的 bean 代理提供了自动 MBeanServer 注册,并支持标准 JSR-160 远程连接器。在最简单的情况下,可以用 Spring JMX 以 MBeanExporter 类注册对象。Spring 自动识别 StandardMBean 或者用 ModelMBean 代理包装对象,在默认情况下使用内省。可以以显式引用使用 BeanExporter 以声明 bean,或者可以用默认策略或更复杂的策略自动检测 bean。
Spring 1.2 提供的大量装配器使得透明地构造 MBean 成为可能,包括使用内省、Standard MBean 接口、元数据(使用类级别注释)和显式声明的方法名。Spring 的基于导出器和装配器的模型容易扩展,并在创建注册的 MBean 时提供所需要的控制能力。
JMX 使用 ObjectName 语言注册和访问管理对象。如果选择使用自动注册,那么 Spring 提供了不同的命名策略。使用“键”命名策略时,可以使用一个属性把 MBean名与 NameObject 实例关联起来。如果实现ManagedResource 接口,那么可以使用元数据命名规范。由于 Spring 高度灵活的体系结构和大量扩展点,还可以实现自已的策略。
在默认情况下,Spring 会发现运行的 MBeanServer 实例,如果没有实例在运行或者没有显式声明的话,它会创建一个默认实例。用 Spring 配置直接实例化自己的 MBeanServer 与使用各种连接器同样容易。Spring 通过客户机和服务器连接提供控制,并提供客户机代理以协助客户端编程。
所有这些功能都是 Spring1.2 默认提供的。虽然 Spring JMX 提供了大量选项,但是默认的导出器对于许多项目来说已经足够了,使您可以很快地投入运行。不过,使用 JMX 时,在使用隐式 MBean 构造时会注意到一些特性。结果,可能会慢慢地从 Standard MBean 转移到 Model MBean,它允许对应用程序的属性、操作和通知元数据施加更多的控制。要保留松散耦合的好处(也就是 Spring 灵活的体系结构内在的优点),需要在 Java 对象之外实现这个控制。
Spring 的 IOC 使得从外部连接(wire)对象依赖性容易了,在 Spring 的体系结构中很容易利用这种优点。IOC保持对象依赖性的可注入性,这使得增加、替换或者补充对象的行为(包括 Spring 的 JMX 支持)变得轻而易举。在本文的其余部分,我将重点放到扩展 Spring JMX 以得到更细化的应用程序管理,而不会搞乱应用程序代码或者破坏 Spring 固有的灵活性。
扩展 Spring JMXSpring 框架提供了许多处理 JMX 的有用工具,包括用于扩展 JMX 功能的扩展点。我将利用它们获得对 MBeanInfo 声明的更多控制,同时不用对 Java 对象施加注释。为此,我将要以两种方式扩展 Spring JMX:第一种方法可以用一个外部 XML 格式(类似于 JBoss 微内核)配置 MBean 元数据,第二种方法可以与其相关联的 Java 对象一同存储在在类路径中(很像 Hibernate映射文件)。
推荐的文章Spring 1.2 的文档有整整一章关于 JMX 的内容,如果想要在 Spring 中使用 JMX 就应该阅读它。有关 Spring 1.2 文档的内容请参阅 参考资料。
我将扩展 RequiredModelMBean 类,让它使用一个简单的命名规范,以 <ClassName>.mbean.xml 格式寻找相关的 MBean 部署描述符。定义这种基于 XML 的 MBean 描述符改进了对应用程序元数据的控制,而不会失去基于 POJO 的设计和 Spring 复合的灵活性。为了实现这一点,我将实现自己的装配器并扩展基本的 Spring JMX 导出器。扩展的导出器可以创建扩展的 ModelMBean,它支持截获属性的改变以及 before 和 after 方法执行的通知。我可以用 Spring 的 AOP 机制完成这一切,但是 ModelMBean 已经是底层受管资源的代理,因此我将用更直接的方式扩展RequiredModelMbean 类。
管理基础不管使用什么技术,在管理资源时有三个要关注的主要领域:
- 属性(attribute) (有时称为属性(property)、字段或者变量)。只读属性对于开放度量或者状态很有用。读/写属性使管理员可以改变配置。
- 动作(action) (可执行调用,对于 Java 代码来说就是方法)。动作用于触发像启动和关闭这样的事件,或者其他特定于应用程序的操作。
- 事件(event) (向监视系统发出的通知,反映状态改变或者一些操作的执行)。通知确认操作或者状态改变确实发生了。通知还可以用于触发事件,如对于超过设置阀值(比如内存或者磁盘空间等资源不足)的状态改变做出反应。这种通知可以用于在系统需要关注时向应用程序管理员发送电子邮件或者传呼。
在扩展 Spring JMX 时,我将用一个简单的案例分别展示这三个需要关注的领域:一个带有开始和停止方法并且有一个读写属性要管理的示例服务。我还要用一个小型的客户机/服务器应用程序测试这个实现,并开放一个使用 MX4J 适配器的 HTTP 管理接口。所有例子将有必要的限制,但是足以使您理解相应的概念。您会看到在基于 Spring 的应用程序方法和属性中加入 JMX 通知事件有多么容易,结果是可以监视状态改变,同时不会在 Java 对象中加入不必要的代码。
MBeanInfo 模型如果下载与本文有关的代码,您会发现一个名为 com.claudeduguay.mbeans.model 的包,它包含一组用于建模 MBeanInfo XML文件的类。这个包包含大量类,因此我不会详细讨论所有类,但是其基本内容还是有必要说明的。
模型的根是 MBeanDescriptor 类,它提供了一个 createMBeanInfo() 方法,负责用应用程序元数据创建一个兼容JMX 的 ModelMBeanInfo 实例。MBeanDescriptorUtil 类提供了两个静态的 read() 方法,它装载并保存这个 XML 文档模型。这个模型中使用的 Document 和 Element 实例基于 JDOM 框架。
我使用的基本 MBeanInfo 相关类和描述符模型是密切相关的。基类中的所有基本属性都是在 XML 中建模的,并可以用简单的格式定义。例如,<mbean> 标记是我的文档的根。它与 ModelMBeanInfo 直接相关,它期待一个 type 和 description 属性。类型是受管 bean 的完全限定类名。不过,在使用我的 Sping 解决方案时,这个类完全可以在上下文中派生。<mbean> 标记期待零个或者多个 attribute、operation、constructor 和 notification 子类型。它们每一个都提供了基 MBeanInfo 类 XML 属性。
图 1. MBean XML 格式MBean 模型实现利用了 com.claudeduguay.util.jdom 包中几个与 JDOM 相关的工具类。它们主要是解析和构建 Document 和 Element 对象的接口,一个工具类使读和写 Document 流更容易。要查看的大多数代码在com.claudeduguay.mbeans.spring 包中。
已经做了足够的预备工作,让我们开始扩展 Spring JMX! |