# MXBean 的 > 原文: [https://docs.oracle.com/javase/tutorial/jmx/mbeans/mxbeans.html](https://docs.oracle.com/javase/tutorial/jmx/mbeans/mxbeans.html) 本节介绍一种特殊类型的 MBean,称为 _MXBeans_ 。 _MXBean_ 是一种 MBean,仅引用一组预定义的数据类型。通过这种方式,您可以确保任何客户端(包括远程客户端)都可以使用您的 MBean,而无需客户端访问表示 MBean 类型的特定于模型的类。 MXBeans 提供了将相关值捆绑在一起的便捷方式,而无需特别配置客户端来处理捆绑包。 与标准 MBean 的方式相同,MXBean 是通过编写名为`SomethingMXBean`的 Java 接口和实现该接口的 Java 类来定义的。但是,与标准 MBean 不同,MXBeans 不需要调用 Java 类`Something`。接口中的每个方法都定义 MXBean 中的属性或操作。注释`@MXBean`也可用于注释 Java 接口,而不是要求接口的名称后跟 MXBean 后缀。 MXBeans 存在于 Java 2 平台标准版(J2SE)5.0 软件的 [`java.lang.management`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/package-summary.html) 包中。但是,除了`java.lang.management`中定义的标准集之外,用户现在还可以定义自己的 MXBean。 MXBeans 背后的主要思想是在 MXBean 接口中引用的 [`java.lang.management.MemoryUsage`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/MemoryUsage.html) 等类型,在这种情况下为 [`java.lang.management.MemoryMXBean`](https://docs.oracle.com/javase/8/docs/api/java/lang/management/MemoryMXBean.html) ,它们被映射到一组标准类型中,所谓*开放类型*,在包 [`javax.management.openmbean`](https://docs.oracle.com/javase/8/docs/api/javax/management/openmbean/package-summary.html) 中定义。确切的映射规则出现在 MXBean 规范中。但是,一般原则是简单类型(如 int 或 String)保持不变,而复杂类型(如`MemoryUsage`]则映射到标准类型 [`CompositeDataSupport`](https://docs.oracle.com/javase/8/docs/api/javax/management/openmbean/CompositeDataSupport.html) 。 MXBean 示例包含以下文件,可在 [`jmx_examples.zip`](../examples/jmx_examples.zip) 中找到: * `QueueSamplerMXBean`接口 * 实现 MXBean 接口的`QueueSampler`类 * `QueueSample` MXBean 接口中`getQueueSample()`方法返回的 Java 类型 * `Main`,设置并运行示例的程序 MXBean 示例使用这些类来执行以下操作: * 定义一个管理`Queue<String>`类型资源的简单 MXBean * 在 MXBean 中声明一个 getter,`getQueueSample`,它在调用时获取队列的快照,并返回将以下值捆绑在一起的 Java 类`QueueSample`: * 拍摄快照的时间 * 队列大小 * 在给定时间排队的队长 * 在 MBean 服务器中注册 MXBean ## MXBean 接口 以下代码显示了示例 [`QueueSamplerMXBean`](../examples/QueueSamplerMXBean.java) MXBean 接口: ```java package com.example; public interface QueueSamplerMXBean { public QueueSample getQueueSample(); public void clearQueue(); } ``` 请注意,您声明 MXBean 接口的方式与声明标准 MBean 接口的方式完全相同。 `QueueSamplerMXBean`接口声明一个 getter,`getQueueSample`和一个操作,`clearQueue`。 ## 定义 MXBean 操作 MXBean 操作在 [`QueueSampler`](../examples/QueueSampler.java) 示例类中声明,如下所示: ```java package com.example; import java.util.Date; import java.util.Queue; public class QueueSampler implements QueueSamplerMXBean { private Queue queue; public QueueSampler (Queue 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 接口声明的`getQueueSample()` getter 和`clearQueue()`操作。 `getQueueSample()`操作返回`QueueSample` Java 类型的实例,该实例是使用 [`java.util.Queue`](https://docs.oracle.com/javase/8/docs/api/java/util/Queue.html) 方法`peek()`和`size()`返回的值创建的,[的实例`java.util.Date`](https://docs.oracle.com/javase/8/docs/api/java/util/Date.html) 。 ## 定义 MXBean 接口返回的 Java 类型 `QueueSampler`返回的`QueueSample`实例在 [`QueueSample`](../examples/QueueSample.java) 类中定义,如下所示: ```java 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 将给定实例转换为 [`CompositeData`](https://docs.oracle.com/javase/8/docs/api/javax/management/openmbean/CompositeData.html) 实例,并使用`@ConstructorProperties`注释重建`QueueSample`实例一个`CompositeData`实例。 ## 在 MBean Server 中创建和注册 MXBean 到目前为止,已经定义了以下内容:MXBean 接口和实现它的类,以及返回的 Java 类型。接下来,必须在 MBean 服务器中创建并注册 MXBean。这些操作由标准 MBean 示例中使用的相同 [`Main`](../examples/Main.java) 示例 JMX 代理执行,但相关代码未显示在[标准 MBean](standard.html) 课程中。 ```java 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 queue = new ArrayBlockingQueue(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`类执行以下操作: * 获取平台 MBean 服务器。 * 为 MXBean `QueueSampler.`创建对象名称 * 为要处理的`QueueSampler` MXBean 创建`Queue`实例。 * 将`Queue`实例提供给新创建的`QueueSampler` MXBean。 * 以与标准 MBean 完全相同的方式在 MBean 服务器中注册 MXBean。 ## 运行 MXBean 示例 MXBean 示例使用您在[标准 MBeans](standard.html) 部分中使用的 [`jmx_examples.zip`](../examples/jmx_examples.zip) 包中的类。此示例需要 Java SE 平台的第 6 版。要运行 MXBeans 示例,请执行以下步骤: 1. 如果尚未这样做,请将 [`jmx_examples.zip`](../examples/jmx_examples.zip) 保存到`work_dir`目录中。 2. 在终端窗口中使用以下命令解压缩示例类包。 ```java unzip jmx_examples.zip ``` 3. 编译`work_dir`目录中的示例 Java 类。 ```java javac com/example/*.java ``` 4. 启动`Main`应用程序。生成`Main`正在等待发生某事的确认。 ```java java com.example.Main ``` 5. 在同一台计算机上的另一个终端窗口中启动 JConsole。将显示“新建连接”对话框,其中列出了可以连接的正在运行的 JMX 代理的列表。 ```java jconsole ``` 6. In the New Connection dialog box, select `com.example.Main` from the list and click Connect. 将显示平台当前活动的摘要。 7. Click the MBeans tab. 此面板显示当前在 MBean 服务器中注册的所有 MBean。 8. In the left frame, expand the `com.example` node in the MBean tree. 您会看到`Main`创建并注册的示例 MBean `QueueSampler`。如果单击`QueueSampler`,则会在 MBean 树中看到其关联的“属性”和“操作”节点。 9. Expand the Attributes node. 您会看到`QueueSample`属性出现在右侧窗格中,其值为`javax.management.openmbean.CompositeDataSupport`。 10. Double-click the `CompositeDataSupport` value. 您会看到`QueueSample`值`date`,`head`和`size`,因为 MXBean 框架已将`QueueSample`实例转换为`CompositeData`。如果您已将`QueueSampler`定义为标准 MBean 而不是 MXBean,则 JConsole 将找不到`QueueSample`类,因为它不在其类路径中。如果`QueueSampler`是标准 MBean,则在检索`QueueSample`属性值时会收到`ClassNotFoundException`消息。 JConsole 找到`QueueSampler`这一事实证明了在通过 JConsole 等通用 JMX 客户端连接到 JMX 代理时使用 MXBeans 的有用性。 11. Expand the Operations node. 显示调用`clearQueue`操作的按钮。 12. Click the `clearQueue` button. 显示已成功调用该方法的确认。 13. Expand the Attributes node again, and double click on the `CompositeDataSupport` value. `head`和`size`值已重置。 14. 要关闭 JConsole,请选择 Connection - >出口。