`

从黑箱到企业: Bean,JMX 1.1 样式

    博客分类:
  • JMX
阅读更多

简单的 GUI 应用程序:ClickMeter

  我们的样本应用程序 ClickMeter 是基于 Swing 的 GUI 实用程序,它以典型的 MVC 设计为特色。它显示了其 GUI 上的“数字计数器”和两个按钮。单击 +按钮递增显示的数字,单击 -按钮则递减显示的数字。表 1 列出了应用程序中的文件:

  表 1. ClickMeter GUI 应用程序中的文件

文件名 描述
ClickMeter.java 带有我们将执行的静态 main 方法的类;它创建 GUI 框架,将其置中并显示它
ClickFrame.java 包含 ClickPanel 的框架容器
ClickPanel.java 单一源文件,包含用于 GUI 应用程序的三个类: ClickPanelModel (模型)、 ClickPanel (视图)和 ClickPanelController (控制器)。

  负责 GUI 表示的视图类是 ClickFrame ,它是 javax.swing.JPanel 的子类。它创建 GUI 元素,将它们布置在面板上并管理用户与 GUI 的交互。ClickMeter 的 MVC 操作如图 1 所示:

  图 1. ClickMeter 的 MVC 交互

  

  在图 1 中, ClickPanelModel (模型)保持一个代表计数器瞬时值的 int 值(名为 val )。要访问该值,您必须通过 ClickPanelModel 类的方法。这些方法包括用于 val 变量的 set() 、 get() 、 increment() 和 decrement() 。 ClickPanel 是典型的 ClickPanelModel 的观察器。无论 ClickPanelModel 值何时更改,它都会通过调用 NotifyUpdate() 方法将更改通知给 ClickPanel 。

  此时, ClickPanel 取出模型已更改的值并将它重新显示在包含该值的 GUI 面板上。这确保了显示在 ClickPanel 上的值始终和 ClickPanelModel 中的值保持一致。为完成这一循环, ClickPanel 管理用户和 GUI 的交互(例如,单击两个按钮中的一个),然后将所有操作都传递给 ClickPanelController (使用 onIncButtonClicked 或 onDecButtonClicked 方法)。 ClickPanelController 通过修改 ClickPanelModel 的值使 GUI 操作与所期望的计数器操作协调。这是通过调用 ClickPanelController 的 incPanelValue() 和 decPanelValue() 方法实现的。

  试验 ClickMeter:不使用 JMX

  使用代码分发版中提供的 compile.bat 批处理文件来编译应用程序,或从代码子目录执行下列命令行:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1 javac -classpath
2         <jmx install dir>\lib\jmxri.jar;
3         <jmx install dir>\lib\jmxtools.jar
4 -d classes src\dwjmxservice\basic\*.java
5       

  使用 runmeter.bat 文件运行应用程序,或者从代码子目录执行下列命令行:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1 java -classpath
2         <jmx install dir>\lib\jmxri.jar;
3         <jmx install dir>\lib\jmxtools.jar;
4 classes dwjmxservice.basic.ClickMeter
5

  图 2 显示了运行的应用程序。您可以在任何时候单击这两个按钮来递增或递减计数器值。

  图 2. ClickMeter GUI 应用程序

  

  要注意的一件很重要的事是,整个应用程序的设计没有考虑可管理性。也就是说,应用程序中完全没有引用任何 JMX 类,并且它不是用任何可使 JMX 代码的添加变得更容易或更困难的方法来构建的。简单地讲,这反映出它是设计良好的 Java GUI 应用程序 - 不关心对 JMX 操作的适应性。而且这也是 JMX 的本质:能很容易地将它添加到任何应用程序或软件服务器/服务,使它们立即成为是可管理的。JMX 的这一“易添加”特性的结果是很低的实现开发成本。接下来,您将看到如何能快速地将工具添加到 ClickMeter 应用程序。

  规划工具

  工具能添加到任何 Java 程序(包括任何软件服务、服务器或应用程序)中。工具涉及可管理的属性(特性)、操作(方法)和事件,它们可以向 JMX 代理公开(并通过这些代理向 EMS 和管理应用程序公开)。JMX 设计者首先必须确定要添加的工具。

  您可以很容易地添加工具来管理联网设备和软件服务/服务器。对于联网设备来说,属性可以是所用设备的 IP 地址和端口、所支持的协议、协议的参数等等。对设备的操作可以包括复位出厂缺省值、重新引导、固件升级等等。对于 Web 应用程序服务器来说,属性可以是每个单位时间“命中”的总数、用在服务器上的 CPU 时间总量或服务器上执行的应用程序的组合。对应用程序服务器进行的操作可以包括复位、重新引导和应用程序在服务器上的装入和卸载。

  但是我们主要关心的是 ClickMeter。ClickMeter 中有什么是要受管的呢?表 2 给出了一些答案:

  表 2. 受管的元素

受管的元素 类型 描述
PanelValue 属性 计数器的瞬时值;和 ClickPanelModel 所保持的值一样
incPanelValue 操作 计数器值加 1;和用户单击 +按钮的操作一样
decPanelValue 操作 计数器值减 1;和用户单击 -按钮的操作一样
 

      添加工具的第一步是确保可管理元素容易访问。为了帮助做到这一点,我们将一些方法添加到 ClickMeter 类中。为了保持原有的 ClickMeter 应用程序 - 让它完全与 JMX 代码无关 - 我们创建 ClickMeter 的子类,称为 ClickMeterInstrm 。该类的方法如表 3 所示:

  表 3. 公开 ClickMeterInstrm 的属性和操作的方法

方法 描述
getPanelValue() 通过模型( ClickPanelModel )获取计数器的当前值
setPanelValue() 通过模型来设置计数器的当前值,因为我们知道 MVC 模式设计将确保所有视图和模型同步。
incPanelValue() 通过模型,使计数器值加 1
decPanelValue() 通过模型,使计数器值减 1
 

     单 1 演示了 ClickMeterInstrm 类的实现:

  清单 1. ClickMeterInstrm 代码 

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1 package dwjmxservice.basic;
2 public class ClickMeterInstrm extends ClickMeter {
3   public ClickMeterInstrm() {
4   }
5   // code added to instrument for JMX Instrumentation
6   public void setPanelValue(Integer val) {
7       frame.clickPanel.myModel.setVal(val.intValue());
8   }
9   public Integer getPanelValue() {
10    return new Integer(frame.clickPanel.myModel.getVal());
11   }
12   public void incPanelValue() {
13   frame.clickPanel.myModel.incVal();
14   }
15   public void decPanelValue() {
16   frame.clickPanel.myModel.decVal();
17   }
18 }
19

  请注意清单 1 中所示的新方法的实现如何使用 ClickPanelModel 来更改计数器的值。 setPanelValue() 和 getPanelValue() 方法/操作提供了符合 JavaBeans 的命名约定,该约定公开了 PanelValue 特性/属性。一旦我们添加标准 Mbean 支持,这就会显得很重要。

  原有的 GUI 应用程序 ClickMeter 仍是原封不动的,完全不受这次添加的影响。

  既然我们已经添加了逻辑来支持对一个属性和两个操作的访问,那么我们可以添加将它们向管理代理公开的机制。要实现这一点,我们将 JMX MBean(受管的 bean,managed bean)支持添加到 ClickMeter 应用程序中。正如我们在 第 1 部分中学到的那样,MBean 实现至少有两种不同的主要样式,如表 4 所示:

  表 4. 两种不同样式的 MBean 实现

MBean 实现 描述
标准 所有属性、操作和事件都在编译时通过固定的管理接口进行定义。
动态 Mbean 所支持的受管属性、操作和事件直到运行时才确定 - 并且可以在调用之间或者甚至在一个管理会话期间动态变化

  将工具添加到 ClickMeter 中最快、最简单的方法是使用标准 MBean 实现。

实现标准 MBean

  在一个标准 MBean 中,向管理代理公开的所有属性、操作和事件都在固定的接口中指定。这个接口的名称必须遵循下面这个词法模式: <服务/应用程序/设备的类名> MBean。

  在我们的示例中,我们已经用标准 MBean 工具创建了一个名叫 ClickMeterStd 的 ClickMeterInstrm 子类,它将包含 ClickMeter 应用程序。由于应用程序名为 ClickMeterStd ,因此标准 MBean 工具必须遵循词法模式,并命名为 ClickMeterStdMBean 。清单 2 定义了 ClickMeterStdMBean.java(可在源代码分发版中获得该文件)的接口:

  清单 2. ClickMeterStdMBean 管理接口

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1 package dwjmxservice.basic;
2 public interface ClickMeterStdMBean {
3   public void setPanelValue(Integer inVal);
4   public Integer getPanelValue();
5   public void incPanelValue();
6   public void decPanelValue();
7 }
8

  在清单 2 中,已公开的属性作为公共的 getter 方法和 setter 方法(用于 PanelValue 属性)列出,并且操作也是公共的方法( incPanelValue() 和 decPanelValue() 操作)。

  JMX 代理将使用标准的 Java 内省(introspection)确定运行时期间 MBean 所支持的属性和操作。现在我们将创建简单的 JMX 代理。

  创建简单的 JMX 代理

  JMX 代理通过 MBeanServer(在 JMX 规范中定义了其接口)装载 MBean。它还提供了一组所需的代理服务,还提供了协议适配器或直接连接到 JMX 管理器或 EMS/NMS 的连接器。

  日益智能化的网络设备、PC 和外围设备的出现,对这些端点的日常管理和监控方面提出了越来越高的智能化要求。而且,通过因特网处理业务的需求日益增长,从而产生了一种新的需要 EMS 支持的端点 - 即智能软件服务器/服务。

  图 3 应使您想起 JMX 代理的组件化组成。在 JMX 体系结构中,代理层聚合 MBean 并公开属性、操作和事件让分布式服务层来管理。代理可以直接传递来自其聚合的 MBean 的可管理元素,或者为其自身可管理元素组提供增值特性和公开。

  图 3. JMX 代理的组成

  

  参考实现提供了一个简单的代理所需的所有元素。但是,唯一完全实现的与外部世界的连接是 HTML 协议适配器。该协议适配器允许 Web 浏览器查看并访问代理所管理的所有 MBean 的可管理元素。

  让我们添加代码以配置代理并使用其协议适配器。我们将对启动 JMX 参考实现代理的支持添加到 ClickMeterStd 中。清单 3 演示了负责实例化和启动该代理的代码:

  清单 3. 用于实例化和启动 JMX 代理的代码

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1 BaseStdAgent myAgent = new BaseStdAgent();
2     myAgent.startAgent((Object) cms);
3

  请注意 BaseStdAgent 类的使用(请参阅源代码分发版中的 BaseStdAgent.java)。本质上,代理中的逻辑包括下列程序步骤:

  启动 MBeanServer。

  向 MBeanServer 注册受管的 MBean。

  启动协议适配器和连接器。

  在生产编码中,将 JMX 规范所需求的大多数代理服务也作为 MBean 装入。这意味着步骤 2 还将注册代理服务的所有 MBean。事实上,就我们在此使用的 HTML 协议适配器而言,它也是 MBean。清单 4 演示了 BaseStdAgent.java 中执行步骤 1 的代码:

  清单 4. BaseStdAgent 中创建和启动 MBeanServer 的代码

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1 System.out.println("Creating the MBeanServer....");
2     MBeanServer server = MBeanServerFactory.createMBeanServer();
3

  清单 5 演示了执行步骤 2 的代码。在这个例子中,将第一个 MBean 作为 inMBean 参数传递给 BaseStdAgent 。我们还给它一个用户可读的 ObjectName 。

  清单 5. 向 MBeanServer 注册受管的 MBean

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1 try {
2         ObjectName tpMBeanName = new ObjectName("MBean:name=ClickMeter");
3         server.registerMBean(inMBean, tpMBeanName);
4       } catch (Exception e) {
5          System.out.println("Cannot register ClickMeter MBean!");
6          e.printStackTrace();
7          return;
8       }
9

  BaseStdAgent 中最后部分的代码启动了 HTML 协议适配器,它位于 com.sun.jdmk.comm.HtmlAdaptorServer 类中。清单 6 演示了如何设置并启动协议适配器。缺省情况,它监控用于 HTML 浏览器连接的端口 8082。请注意用于注册 HTML 协议适配器的 server.registerMBean() 方法的使用,其本身就是 MBean。

  清单 6. 创建和启动 HTML 协议适配器

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1 System.out.println("Creating an HTML protocol adaptor..");
2     HtmlAdaptorServer hadaptor = new HtmlAdaptorServer();
3     ObjectName adaptorName = null;
4     try {
5         adaptorName = new ObjectName("Adaptor:name=hadaptor,port=8082");
6         server.registerMBean(hadaptor, adaptorName);
7     } catch(Exception e) {
8         System.out.println("Cannot create the HTML protocol adaptor!");
9         e.printStackTrace();
10         return;
11     }
12     hadaptor.start();
13

  以上是这个简单代理中的所有代码。如果要支持更多的代理服务,可以用和 HTML 协议适配器同样的方式向 MBeanServer 注册它们。

  要注意的是,这个简单 JMX 代理的代码是独立于它要管理的 MBean( ClickMeterStd 和 HtmlAdaptorServer )编写的。同样,MBean 代码是独立于最终用来管理它的代理编写的。这是 JMX 多层体系结构的本质。工具层的 MBean 旨在与代理层的代理逻辑松散去耦合。

通过 HTML 协议适配器连接至 JMX 代理

  使用 compile.bat 文件编译具有全部工具和代理支持的 ClickMeterStd 应用程序,或者从代码子目录执行下列命令行:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1 javac -classpath
2         <jmx install dir>\lib\jmxri.jar;
3         <jmx install dir>\lib\jmxtools.jar
4 -d classes src\dwjmxservice\basic\*.java
5

  使用 runstd.bat 文件启动 ClickMeterStd 应用程序,或者从代码子目录执行下列命令行:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1 java -classpath
2         <jmx install dir>\lib\jmxri.jar;
3         <jmx install dir>\lib\jmxtools.jar;
4 classes dwjmxservice.basic.ClickMeterStd
5

  这条命令启动了 ClickMeter 应用程序以及 JMX 代理。试一试 ClickMeter 应用程序中的按钮。因为我们添加 JMX 工具时没有更改一行 ClickMeter 代码,所以 ClickMeter 仍然像以前那样工作。但是,ClickMeter 的标准 MBean 已被装入 JMX 代理并且已经启动了 HTML 适配器。这允许我们立即访问代理。启动浏览器并指向:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1 http://localhost:8082/

  您将会看到类似于图 4 的代理产生的页面:

  图 4. 针对 HTML 协议适配器的主代理视图页面

  

  我们可以看到由这个代理管理的所有 MBean。单击 name=ClickMeter。您将看到类似图 5 的页面:

  图 5. 针对 HTML 协议适配器的详细的 ClickMeter MBean 视图

  

  请注意由 MBean 公开的 PanelValue 属性以及 incPanelValue 和 decPanelValue 操作。如果您设置了重新装入时间,那么来自代理的客户机端 JavaScript 代码将定期地轮询 PanelValue 属性的值并更新所显示的值。尝试使用 5 到 10 秒的重新装入时间并查看更新情况。您还可以单击 ClickMeter 上的 GUI 按钮来更改该值。

  接下来,尝试以下操作:

  单击 incPanelMeter 操作以递增计数器的值。请注意我们是如何轻松地访问该操作的 - 如 JMX 管理应用程序可以通过代理做的那样。

  单击 decPanelMeter 操作。

  设置 PanelValue 属性的值。请注意它在 ClickMeter 中是如何立即被更新的。

  尽管在这个例子中我们使用 HTML 协议适配器,而其它协议适配器或连接器(例如 SNMP)也可以容易地使用,并且它们将通过其它应用程序或 EMS 使我们的 ClickMeter 成为可管理的。

  还记得我们说过不必将 ClickMeterStd MBean 所支持的属性和操作显式地告诉代理吗。代理实际上在运行时期间通过内省 ClickMeterStdMBean 接口发现它自己。这是使用标准 MBean 时 JMX 的标准操作。代理在运行时期间使用内省定位该管理接口(借助于必需的标准 MBean 词法命名模式)。

  动态 MBean

  动态 MBean 是实现 java.management.DynamicMBean 接口的 MBean。表 5 演示了该接口必须实现的方法:

  表 5. 动态 MBean 接口方法

方法名 描述
getAttribute() 获取属性名称,然后将其当前值作为 Java 对象返回
getAttributes() 获取一列属性的名称,然后,如果它们的当前值可用就将其作为 Java 对象返回
setAttribute() 给属性设置特定值
setAttributes() 设置一列属性的值
invoke() 调用特定的操作;如果适用,就提供参数并支持返回值
 

     和标准 MBean 不同的是,代理依靠 DynamicMBean 接口在运行时从 MBean 获得公开的属性、操作和事件的元数据信息。这意味着当您将工具添加到应用程序中时没必要遵循词法模式(JavaBeans 编码约定)。代理使用动态 MBean 时不需要对 MBean 执行内省。它信任从 bean 接收到的元数据,该 bean 由 getMBeanInfo() 调用。因为 MBean 在运行时期间生成这个数据,所以有可能无需重新编码静态定义的接口就可以更改该数据。开始使用动态 MBean 的最快捷的方法是使用 ModelMBean 。

  瞬时动态 MBean 支持:ModelMBean

  ModelMBean 是存在于所有 JMX 实现之中的必需的缺省 MBean 实现。JMX 规范精确地规定了如何访问 ModelMBean 实例。因为它完全由 JMX 实现来实现的,所以模型 MBean 的优点在于它的易于使用和适应性。通常在运行时,应用程序、服务、服务器或设备可以将 ModelMBean 实例实例化成其它 JMX 层的表示。

  模型 MBean 始终是动态 MBean(它必须是动态的,因为没有办法让它预先知道它的用户是谁,也就是说可以不预先知道公开的属性、操作和事件)。另外,模型 MBean 为任意软件应用程序、服务、服务器或设备提供了现成可用的 MBean 外观(或封装器)。而且模型 MBean 保证是可兼容的,因为它是实现的自身代码的一部分。

  使用 ModelMBean 添加工具

  让我们研究一下如何使用 ModelMBean 快速地将动态 MBean 工具添加到 ClickMeter 中。我们创建一个新的 ClickMeterInstrm 子类 - 名为 ClickMeterMod 。清单 7 演示了该类的代码:

  清单 7. ClickMeterMod - 使用 ModelMBean 的工具

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1 public class ClickMeterMod extends ClickMeterInstrm  {
2   public ClickMeterMod() {
3   }
4   public static void main(String[] args) {
5     setLandF();
6     ClickMeterMod cms = new ClickMeterMod();
7     BaseModAgent myAgent = new BaseModAgent();
8     myAgent.startAgent((Object) cms);
9   }
10 }
11

  请注意,清单 7 中 ClickMeterMod 类不实现任何特定的接口。它和任何编译时 JMX 需求都是完全去耦合的。这是因为我们将在运行时期间使用 JMX 参考实现中已有的模型 MBean 实现将它挂接到 JMX。这实际上是在由 BaseModAgent 类代表的代理中执行的。

JMX 代理中模型 MBean 的运行时挂接

  当您使用 ModelMBean 实现时,唯一必需的工作就是向 ModelMBean “封装器”实例提供合适的 ModelMBeanInfo 结构。清单 8 显示了来自 BaseModAgent 类的摘录:

  清单 8. BaseModAgent.java 中 RequiredModelMBean 的运行时挂接

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1 try {
2         ObjectName tpMBeanName = new ObjectName("MBean:name=ClickMeter");
3         RequiredModelMBean modelmbean =
4           new   RequiredModelMBean(createMBeanInfo());
5         modelmbean.setManagedResource(inManagedObj, "objectReference");
6         server.registerMBean(modelmbean, tpMBeanName);
7       } catch (Exception e) {
8          System.out.println("Cannot register ClickMeter MBean!");
9          e.printStackTrace();
10          return;
11       }
12

  在清单 8 中,通过对本地 createMBeanInfo() 方法的调用对 javax.management.modelmbean.RequiredModelMBean 进行实例化。这种方法将创建描述由 MBean 公开的属性、操作和事件的元数据。另外请注意我们调用了 RequiredModelMBean 的 setManagedResource() 方法,向它提供 ClickMeterMod 这一“要封装的类”的引用。事实上,通过使用 JMX 参考实现,该引用还可以是 RMI 引用或 CORBA IOR - 允许使用 ModelMBean 方便地“工具化”远程资源。最后,请注意当我们在 MBeanServer 上调用 registerMBean() 时,我们注册的是 RequiredModelMBean 封装器实例,而不是非 MBean 的 ClickMeterMod 。图 6 显示了 RequiredModelMBean 在运行时期间是如何工作的:

  图 6. RequiredModelMBean 的运行时操作

  

  图 6 说明了代理层如何只与 RequiredModelMBean 实例一起工作,而 RequiredModelMBean 实例又依次将属性的访问和操作映射到真正封装的 ClickMeterMod 类。这就减轻了对部分封装类的 JMX 相关性的任何要求。

  填充 ModelMBean 元数据

  实例化 RequiredModelMBean 实例时会向其提供元数据描述符。该描述符是 javax.management.modelmbean.ModelMBeanInfo 类的实例。它包含关于封装类公开的属性、操作和事件的全部信息(而且,更重要的是,还包含 RequiredModelMBean 应如何访问它们的信息)。 RequiredModelMBean 将在运行时生成它自己的元数据以代表封装类支持 DynamicMBean 接口。清单 9 显示了 createMBeanInfo() 方法中的这段代码:

  清单 9. 在 createMBeanInfo() 方法中创建 ModelMBean 元数据

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1 private ModelMBeanInfo createMBeanInfo() {
2   Descriptor atDesc = new DescriptorSupport(new String[] {
3                  "name=PanelValue",
4                  "descriptorType=attribute",
5                  "default=0",
6                  "displayName=Value of the Panel",
7                  "getMethod=getPanelValue",
8                  "setMethod=setPanelValue"
9                 }
10                 );
11     ModelMBeanAttributeInfo [] mmbai = new ModelMBeanAttributeInfo[1];
12     mmbai[0] = new ModelMBeanAttributeInfo("PanelValue","java.lang.Integer",
13       "The ClickMeter Value",  true,true, false, atDesc);
14     ModelMBeanOperationInfo [] mmboi = new ModelMBeanOperationInfo[4];
15     mmboi[0] = new ModelMBeanOperationInfo("incPanelValue",
16     "increment the meter value", null, "void", ModelMBeanOperationInfo.ACTION
17     );
18     mmboi[1] = new ModelMBeanOperationInfo("decPanelValue",
19     "decrement the meter value", null, "void", ModelMBeanOperationInfo.ACTION
20     );
21     mmboi[2] = new ModelMBeanOperationInfo("getPanelValue",
22     "getter for PanelValue", null,"Integer", ModelMBeanOperationInfo.INFO);
23     MBeanParameterInfo [] mbpi = new MBeanParameterInfo[1];
24     mbpi[0] =  new MBeanParameterInfo("inVal", "java.lang.Integer",
25       "value to set");
26     mmboi[3] = new ModelMBeanOperationInfo("setPanelValue",
27       "setter for PanelValue", mbpi, "void", ModelMBeanOperationInfo.ACTION);
28     ModelMBeanConstructorInfo [] mmbci = new ModelMBeanConstructorInfo[1];
29     mmbci[0] = new ModelMBeanConstructorInfo("ClickMeterMod",
30     "constructor for Model Bean Sample", null);
31     return new ModelMBeanInfoSupport("dwjmxservice.basic.ClickMeterMod",
32     "dw ModelMBean example", mmbai, mmbci, mmboi, null);
33     }
34

  在清单 9 中要注意的重要特性是 javax.management.modelmbean.ModelMBeanInfoSupport 类如何提供现成可用的 MBeanInfo 实现。事实上,整个方法都在处理这个支持类实例的实例化工作。要对它适当进行实例化,您必须提供封装类的完全限定名称以及描述,然后是指定将要公开的属性、构造器、操作和事件的四个附加参数。该方法的大多数代码主要是创建 ModelMBeanAttributeInfo 、 ModelMBeanConstructorInfo 和 ModelMBeanOperationInfo 数组,这些数组都是 ModelMBeanInfoSupport 类构造器的参数。请注意,用于 PanelValue 属性的 getter 方法和 setter 方法在操作的元数据中被再次定义。这是必需的,因为在封装类中不要求遵循词法模式(命名约定)。另外, RequiredModelMBean 信任所提供的元数据并且将不在封装类上执行额外的内省(如果引用是远程的或是基于 CORBA 的,那么这个操作甚至是不可能的)。

  测试基于模型 MBean 的工具

  使用 compile.bat 文件编译模型 MBean 示例,或者执行下列命令行:

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1 javac -classpath
2         <jmx install dir>\lib\jmxri.jar;
3         <jmx install dir>\lib\jmxtools.jar
4 -d classes src\dwjmxservice\basic\*.java
5                 
6

  使用 runmod.bat 文件运行模型 MBean 示例,或者从代码子目录执行下列命令行:

  java -classpath

  \lib\jmxri.jar;

  \lib\jmxtools.jar;

  classes dwjmxservice.basic.ClickMeterMod

  当您使用 HTTP 协议适配器测试这个 MBean 时,请注意从代理操作的角度来看,它几乎没什么不同。唯一的区别是,用于 PanelValue 的 getter 方法和 setter 方法操作还可以通过 Web 页面独立地使用。

  不必使用 RequriedModelMBean 类对 JMX 执行“快速修改”,您可以通过对 DynamicMBean 接口直接编码来创建灵活得多的动态 MBean。

不用 RequiredModelMBean 来实现 DynamicMBean

  将动态 MBean 工具添加到 ClickMeter 类是有关实现 javax.management.DynamicMBean 接口的所有方法的问题。我们创建名为 ClickMeterDyn 的 ClickMeterInstrm 子类来做到这一点。清单 10 显示了 ClickMeterDyn 的代码:

  清单 10. 实现 DynamicMBean 接口

<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1 package dwjmxservice.basic;
2 import javax.management.MBeanInfo;
3 import javax.management.DynamicMBean;
4 import javax.management.Attribute;
5 import javax.management.AttributeList;
6 import javax.management.MBeanInfo;
7 import javax.management.MBeanAttributeInfo;
8 import javax.management.MBeanConstructorInfo;
9 import javax.management.MBeanOperationInfo;
10 public class ClickMeterDyn extends ClickMeterInstrm implements DynamicMBean {
11   public ClickMeterDyn() {
12   }
13   public static void main(String[] args) {
14    setLandF();
15    ClickMeterDyn cms = new ClickMeterDyn();
16     // can use standard MBean agent - same logic
17     BaseStdAgent myAgent = new BaseStdAgent();
18     myAgent.startAgent((Object) cms);
19   }
20 //<span style
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics