MXBeans

本节说明一种特殊的 MBean,称为 MXBean。

MXBean 是一种 MBean,仅引用一组 预定义的数据类型。这样,您可以确保您的 MBean 可被任何 Client 端(包括远程 Client 端)使用,而无需 Client 端有权访问代表 MBean 类型的特定于模型的类。 MXBean 提供了一种方便的方法来将相关值 Binding 在一起,而无需将 Client 端特别配置为处理 Binding。

以与标准 MBean 相同的方式,通过编写称为SomethingMXBean的 Java interface和实现该interface的 Java 类来定义 MXBean。但是,与标准 MBean 不同,MXBean 不需要将 Java 类称为Something。interface中的每个方法都定义 MXBean 中的属性或操作。注解@MXBean也可以用于 注解Java interface,而不是要求interface名称后跟 MXBean 后缀。

MXBeans 存在于 Java 2 平台标准版(J2SE)5.0 软件中,其名称为java.lang.management。但是,除了java.lang.management中定义的标准集之外,用户现在还可以定义自己的 MXBean。

MXBeans 的主要思想是将 MXBean interface中引用的java.lang.management.MemoryUsage之类的情况(在本例中为java.lang.management.MemoryMXBean)Map 到一组标准类型,即在包javax.management.openmbean中定义的所谓的“开放类型”。确切的 Map 规则出现在 MXBean 规范中。但是,一般原则是使诸如 int 或 String 之类的简单类型保持不变,而将诸如MemoryUsage之类的复杂类型 Map 到标准类型CompositeDataSupport

MXBean 示例由以下文件组成,可以在jmx_examples.zip中找到:

  • QueueSamplerMXBeaninterface

  • QueueSampler实现 MXBean interface的类

  • MXBean interface中getQueueSample()方法返回的QueueSample Java 类型

  • Main,该程序可设置并运行示例

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

  • 定义一个简单的 MXBean,用于 管理Queue<String>类型的资源

  • 在 MXBean 中声明一个吸气剂getQueueSample,该吸气剂在被调用时拍摄队列快照,并返回将以下值 Binding 在一起的 Java 类QueueSample

  • 拍摄快照的时间

    • 队列大小

    • 在给定时间的队列头

  • 在 MBean 服务器中注册 MXBean

MXBean Interface

以下代码显示示例QueueSamplerMXBean MXBean interface:

package com.example; 
 
public interface QueueSamplerMXBean { 
    public QueueSample getQueueSample(); 
    public void clearQueue(); 
}

请注意,您声明 MXBean interface的方式与声明标准 MBean interface的方式完全相同。 QueueSamplerMXBeaninterface声明一个吸气剂getQueueSample和一个操作clearQueue

定义 MXBean 操作

MXBean 操作在QueueSampler示例类中声明,如下所示:

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 interface声明的getQueueSample() getter 和clearQueue()操作。 getQueueSample()操作返回QueueSample Java 类型的实例,该实例是使用java.util.Queue方法peek()size()返回的值以及java.util.Date实例创建的。

定义 MXBean interface返回的 Java 类型

QueueSampler返回的QueueSample实例在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 将给定实例转换为CompositeData实例,并使用@ConstructorProperties注解从CompositeData实例重建QueueSample实例。

在 MBean 服务器中创建和注册 MXBean

到目前为止,已经定义了以下内容:MXBean interface和实现它的类,以及返回的 Java 类型。接下来,必须创建 MXBean 并在 MBean 服务器中注册。这些动作由在标准 MBean 示例中使用的同一Main示例 JMX 代理执行,但相关的代码未在Standard MBean类中显示。

package com.example; 
 
import java.lang.management.管理Factory; 
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 = 
            管理Factory.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.创建对象名称

  • 创建一个Queue实例供QueueSampler MXBean 处理。

  • Queue实例提供给新创建的QueueSampler MXBean。

  • 以与标准 MBean 完全相同的方式在 MBean 服务器中注册 MXBean。

运行 MXBean 示例

MXBean 示例使用您在Standard MBeans部分中使用的jmx_examples.zipBinding 包中的类。此示例需要 Java SE 平台的版本 6.要运行 MXBeans 示例,请按照下列步骤操作:

  • 如果尚未这样做,请将jmx_examples.zip保存到work_dir目录中。

  • 通过在终端窗口中使用以下命令来解压缩 samples 类包。

unzip jmx_examples.zip
  • work_dir目录中编译示例 Java 类。
javac com/example/*.java
  • 启动Main应用程序。确认Main正在 await 某事发生。
java com.example.Main
  • 在同一台计算机上的另一个终端窗口中启动 JConsole。将显示“新建连接”对话框,其中列出了可以连接的正在运行的 JMX 代理。
jconsole
  • 在“新建连接”对话框中,从列表中选择com.example.Main,然后单击“连接”。

显示平台当前活动的摘要。

  • 单击“ MBeans”选项卡。

此面板显示当前在 MBean 服务器中注册的所有 MBean。

  • 在左框架中,展开 MBean 树中的com.example节点。

您将看到由Main创建和注册的示例 MBean QueueSampler。如果单击QueueSampler,则会在 MBean 树中看到其关联的 Attributes 和 Operations 节点。

  • 展开“属性”节点。

您会看到QueueSample属性出现在右窗格中,其值为javax.management.openmbean.CompositeDataSupport

  • Double 击CompositeDataSupport值。

您会看到QueueSampledateheadsize,因为 MXBean 框架已将QueueSample实例转换为CompositeData。如果您已将QueueSampler定义为标准 MBean 而不是 MXBean,则 JConsole 将不会找到QueueSample类,因为它不在其 Classpath 中。如果QueueSampler是标准 MBean,则在检索QueueSample属性值时您将收到ClassNotFoundException消息。 JConsole 找到QueueSampler的事实说明了通过通用 JMXClient 端(例如 JConsole)连接到 JMX 代理时使用 MXBean 的有用性。

  • 展开“操作”节点。

显示调用clearQueue操作的按钮。

  • 点击clearQueue按钮。

显示该方法已成功调用的确认。

  • 再次展开“属性”节点,然后 Double 击“ CompositeDataSupport”值。

headsize值已重置。

  • 要关闭 JConsole,请选择连接->退出。