MXBean是一种引用预定义数据类型的MBean。通过这种方式,您可以确保任何客户机(包括远程客户机)都可以使用您的MBean,而不需要客户机访问代表MBean类型的特定的类。MXBean提供一种方便的方法来绑定数据,而不需要客户端进行特殊的绑定操作。
类似于标准MBean,MXBean定义一个名为SomethingMXBeans的java接口和一个java类实现。然而,不同于标准MBans,MXBeans不需要java实现类必须名为Something。每个接口中的方法定义属性或者操作。@MXBean注解可以用于注解Java接口,这样接口的名称就不必以MXBean为结尾了。
MXBeans包含于J2SE 5.0版本的java.lang.management包中。然而,除了java.lang.management中定义的一组标准MXBeans,使用者可以定义自己的MXBeans。
MXBeans的主要思想是:MXBean接口java.lang.management.MemoryMBean 中引用的诸如java.lang.managementMemoryUsage类型,该类型映射一组称之为开放类型(定义为javax.management.openbean包中)的类型。映射的具体规则详见MXBean规范。然而,对于简单的诸如int、String类型的映射规则保持不变,而对于复杂类型MemoryUsage则映射为基本类型CompositeDataSupport。
MXBean的例子由如下文件构成,你可以在jmx_examples.zip中找到。
MXBean例子上述这些类实现如下动作:
2.3.1. MXBean接口
如下代码展示示例QueueSamplerMXBean的MXBean接口:
package com.example;
public interface QueueSamplerMXBean {
public QueueSample getQueueSample();
public void clearQueue();
}
注意,你声明一个MXBean接口的方式与声明标准MBean接口的方式完全相同。QueueSamplerMXBean接口定义getter方法:getQueueSample和操作clearQueue。
2.3.2. 定义MXBean操作
QueueSampler例子中定义的MXBean操作如下:
package com.example;
import java.util.Date;
import java.util.Queue;
public class QueueSampler
implements QueueSamplerMXBean {
private Queue<String> queue;
public QueueSampler (Queue<String> queue) {
this.queue = queue;
}
public QueueSample getQueueSample() {
synchronized (queue) {
return new QueueSample(new Date(),
queue.size(), queue.peek());
}
}
public void clearQueue() {
synchronized (queue) {
queue.clear();
}
}
}
QueueSampler实现MXBean接口中定义的getter方法getQueueSampler和clearQueue操作。getQueueSample操作返回QueueSample类的实例,该实例由java.util.Queue的peek方法和size方法和java.util.Data实例构造而成。
2.3.3. 定义MXBean接口返回的Java类型
QueueSampler 返回QueueSample类型的实例,代码如下:
package com.example;
import java.beans.ConstructorProperties;
import java.util.Date;
public class QueueSample {
private final Date date;
private final int size;
private final String head;
@ConstructorProperties({"date", "size", "head"})
public QueueSample(Date date, int size,
String head) {
this.date = date;
this.size = size;
this.head = head;
}
public Date getDate() {
return date;
}
public int getSize() {
return size;
}
public String getHead() {
return head;
}
}
在QueueSample类中,MXBean框架调用QueueSample中所有的getter 方法将自己转化为CompositeDate类型的实例,同时使用@ConstructorProperities注解从CompositeData实例转化为QueueSample实例。
2.3.4. 在MBean server中创建并注册MXBean
截至目前,已经定义如下内容:一个MXBean接口和它的实现类,以及实现类的返回类型。然后,MXBean必须在MXBean server进行注册。这些操作同样由标准MBean中的Main启动JMX代理,只不过相关的代码在标准MBean章节中没有介绍。
package com.example;
import java.lang.management.ManagementFactory;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import javax.management.MBeanServer;
import javax.management.ObjectName;
public class Main {
public static void main(String[] args) throws Exception {
MBeanServer mbs =
ManagementFactory.getPlatformMBeanServer();
...
ObjectName mxbeanName = new ObjectName("com.example:type=QueueSampler"); Queue<String> queue = new ArrayBlockingQueue<String>(10);
queue.add("Request-1");
queue.add("Request-2");
queue.add("Request-3"); QueueSampler mxbean = new QueueSampler(queue);
mbs.registerMBean(mxbean, mxbeanName); System.out.println("Waiting...");
Thread.sleep(Long.MAX_VALUE);
}
}
Main执行如下操作:
2.3.5. 运行MXBean实例
MXBean实例详见jmx_examples.zip。本例需要Java SE 6版本以上。运行步骤如下:
a)保存jmx_examples.zip到工作目录。
b)在终端窗口中解压压缩包。
Unzip jmx_exampless.zip
c)在工作目录中编译Java代码。
Javac com/example/*.java
d)启动Main应用。终端会打印提示信息。
Java com.example.Main
e)在本机不同的窗口中启动JConsole。在新建连接对话框中,展示当前可连接的JMX代理列表。
Jconsole
f)在新建连接对话框中,选择com.example.Main并点击连接按钮。当前平台的活动会展示出来。
g)点击MBean标签。该标签展示当前注册到MBean server的MBeans。
h)在左侧框架中,展开MBean树形结构中的com.example节点。你将可以看到QueueSampler。如果你点击QueueSampler,你将看到暴露出来的属性和方法。
i)展开属性节点。你可以看到QueueSample属性出现在右侧标签中,其值为javax.management.openmbean.CompositeDataSupport。
j)双击CompositeDataSupport。你可以看到QueueSample中date、head和size属性(MXBean框架将QueueSample实例转换为ComositeData)。如果将QueueSampler定义为标准的MBean而不是MXBean,JConsole就不会发现QueueSample类,因为它不会在它的类路径中。如果QueueSampler是一个标准的MBean,在访问QueueSample属性值时,您将收到一个ClassNotFoundException消息。通过JConsole等通用JMX客户机连接到JMX代理时,QueueSampler演示了使用mxbean的有用性。
k)展开操作节点。可以看到clearQueue操作的按钮。
l)点击clearQueue按钮。窗口会提示clearQueue方法被调用。
m)再次展开属性节点,双击CompositeDataSupport,head和sie的值将被重置。
通过“连接”->“退出”关闭JConsole。