Java管理扩展特殊MBean之MXBean学习

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中找到。

  • QueueSampler定义MXBean接口
  • 实现上面接口的QueueSampler类
  • MXBean 接口的getQueueSample方法返回类型QueueSample类
  • Main类,程序启动类

MXBean例子上述这些类实现如下动作:

  • 定义简单的MXBean,管理Queue<String>类型的资源
  • 定义getter方法:getQueueSample返回Queue的快照QueueSample类,该类将如下类绑定在一起。
    • 快照时间
    • 队列queue大小
    • 特定时间队列queue的头部
  • 将MXBean注册到MBean server

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执行如下操作:

  • 获得MBean server平台。
  • 为MXBean:QueueSampler创建对象名。
  • 为MXBean:QueueSampler创建一个Queue的实例。
  • 将Queue的实例传递给QueueSampler。
  • 将MXBean注册到MXBean server中。

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。

原文发布于微信公众号 - Java学习网(javalearns)

原文发表时间:2018-10-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏北京马哥教育

Python实现线程安全队列

作者:愤怒的屎壳螂 来源:http://blog.csdn.net/hit0803107/article/details/52876143 最近学习spa...

48570
来自专栏Java成神之路

Spring_总结_04_高级配置(五)_运行时注入值

当讨论依赖注入的时候,我们通常所讨论的是将一个bean引用注入到另一个bean的属性或者构造参数中。它通常指的是将一个对象与另一个对象进行关联。

12420
来自专栏java技术学习之道

Spring中获取request的几种方法,及其线程安全性分析

28370
来自专栏武培轩的专栏

Runtime源码解析(JDK1.8)

package java.lang; import sun.reflect.CallerSensitive; import sun.reflect.Refle...

37790
来自专栏大闲人柴毛毛

跟着柴毛毛学Spring(1)——纵观Spring

Spring根本任务 Spring的根本任务就是简化Java开发。 目前许多框架如果要使用他们,就必须要继承或实现这些框架的各种类。这使得框架与我们的程序...

35540
来自专栏xingoo, 一个梦想做发明家的程序员

基于Dubbo的http自动测试工具分享

公司是采用微服务来做模块化的,各个模块之间采用dubbo通信。好处就不用提了,省略了之前模块间复杂的http访问。不过也遇到一些问题: PS: Githu...

49880
来自专栏无题

堆外内存概要

DirectByteBuffer JDK中使用 DirectByteBuffer对象来表示堆外内存,每个 DirectByteBuffer对象在初始化时,都会创...

25740
来自专栏java闲聊

# SpringBoot thymeleaf基本使用

54540
来自专栏青青天空树

spring基础(1:基本概念)

本系列笔记来自对《Spring实战》第三版的整理,Spring版本为3.0   spring是为了解决企业级应用开发的复杂性而创建的,spring最根本的...

13020
来自专栏蓝天

RPC的实现

RPC全称为Remote Procedure Call,即远过程调用。如果没有RPC,那么跨机器间的进程通讯通常得采用消息,这会降低开发效率,也会增加网络...

27530

扫码关注云+社区

领取腾讯云代金券