751.md 9.5 KB
Newer Older
W
init  
wizardforcel 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
# 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) 中找到:

W
wizardforcel 已提交
17
*   `QueueSamplerMXBean`接口
W
init  
wizardforcel 已提交
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
*   实现 MXBean 接口的`QueueSampler`
*   `QueueSample` MXBean 接口中`getQueueSample()`方法返回的 Java 类型
*   `Main`,设置并运行示例的程序

MXBean 示例使用这些类来执行以下操作:

*   定义一个管理`Queue<String>`类型资源的简单 MXBean
*   在 MXBean 中声明一个 getter,`getQueueSample`,它在调用时获取队列的快照,并返回将以下值捆绑在一起的 Java 类`QueueSample`
    *   拍摄快照的时间
    *   队列大小
    *   在给定时间排队的队长
*   在 MBean 服务器中注册 MXBean

## MXBean 接口

以下代码显示了示例 [`QueueSamplerMXBean`](../examples/QueueSamplerMXBean.java) MXBean 接口:

```
package com.example; 

public interface QueueSamplerMXBean { 
    public QueueSample getQueueSample(); 
    public void clearQueue(); 
} 

```

请注意,您声明 MXBean 接口的方式与声明标准 MBean 接口的方式完全相同。 `QueueSamplerMXBean`接口声明一个 getter,`getQueueSample`和一个操作,`clearQueue`

## 定义 MXBean 操作

MXBean 操作在 [`QueueSampler`](../examples/QueueSampler.java) 示例类中声明,如下所示:

```
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 接口声明的`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) 类中定义,如下所示:

```
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) 课程中。

```
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`类执行以下操作:

*   获取平台 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.  在终端窗口中使用以下命令解压缩示例类包。

    ```
    unzip jmx_examples.zip

    ```

3.  编译`work_dir`目录中的示例 Java 类。

    ```
    javac com/example/*.java

    ```

4.  启动`Main`应用程序。生成`Main`正在等待发生某事的确认。

    ```
    java com.example.Main

    ```

5.  在同一台计算机上的另一个终端窗口中启动 JConsole。将显示“新建连接”对话框,其中列出了可以连接的正在运行的 JMX 代理的列表。

    ```
    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 - &gt;出口。