JMX学习笔记(2)

MBean示例


1. Standard MBeans

Standard MBean要求定义一个名称以“MBean”结尾的接口及对应的实现,例如“SomethingMBean”接口及“Something”实现类。

示例代码: 

/**
 * Standard MBean接口
 */
public interface HelloMBean {
    public void sayHello();
    public int add(int x, int y);
    public String getName();
    public int getCacheSize();
    public void setCacheSize(int size);
}

/**
 * Standard MBean实现类
 */
public class Hello implements HelloMBean {
    private final String name = "Reginald";
    private int cacheSize = DEFAULT_CACHE_SIZE;
    private static final int DEFAULT_CACHE_SIZE = 200;

    @Override
    public void sayHello() {
        System.out.println("hello, world");
    }

    @Override
    public int add(int x, int y) {
        return x + y;
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public int getCacheSize() {
        return this.cacheSize;
    }

    @Override
    public synchronized void setCacheSize(int size) {
        this.cacheSize = size;
        System.out.println("Cache size now " + this.cacheSize);
    }

启动JConsole,打开MBean标签,可以看到StandardMBean的属性和操作:

JMX学习笔记(2)_第1张图片

修改属性或调用方法,可以看到控制台输出:

JMX学习笔记(2)_第2张图片


2. 通知

为发送通知,MBean必须实现接口NotificationBroadcaster或其子接口(如NotificationEmitter),然后创建类javax.management.Notification或其子类(如AttributeChangedNotification)的实例,并传递给NotificationBroadcasterSupport.sendNotification方法。

示例代码:

/**
 * Standard MBean with notification
 */
public interface NotifyMBean {
    public void sayHello();
    public int add(int x, int y);
    public String getName();
    public int getCacheSize();
    public void setCacheSize(int size);
}

/**
 * implementation of Standard MBean with notification
 */
public class Notify extends NotificationBroadcasterSupport implements NotifyMBean {
    private final String name = "Reginald";
    private int cacheSize = DEFAULT_CACHE_SIZE;
    private static final int DEFAULT_CACHE_SIZE = 200;
    private long sequenceNumber = 1;

    @Override
    public void sayHello() {
        System.out.println("hello, world");
    }

    @Override
    public int add(int x, int y) {
        return x + y;
    }

    @Override
    public String getName() {
        return this.name;
    }

    @Override
    public int getCacheSize() {
        return this.cacheSize;
    }

    @Override
    public synchronized void setCacheSize(int size) {
        int oldSize = this.cacheSize;
        this.cacheSize = size;

        System.out.println("Cache size now " + this.cacheSize);

        Notification n =
                new AttributeChangeNotification(this,
                sequenceNumber++,
                System.currentTimeMillis(),
                "CacheSize changed",
                "CacheSize",
                "int",
                oldSize,
                this.cacheSize);

        sendNotification(n);
    }

    @Override
    public MBeanNotificationInfo[] getNotificationInfo() {
        String[] types = new String[]{
            AttributeChangeNotification.ATTRIBUTE_CHANGE
        };
        String className = AttributeChangeNotification.class.getName();
        String description = "An attribute of this MBean has changed";
        MBeanNotificationInfo info = new MBeanNotificationInfo(types, className, description);
        return new MBeanNotificationInfo[]{info};
    }
}

MBean的实现类继承了NotificationBroadcasterSupport类(该类实现了NotificationBroadcaster接口)。

注意setCacheSize方法中构建的Notification对象及sendNotification方法调用。

getNotificationInfo方法是NotificationBroadcaster接口中声明的,用于返回一个数组,指示此MBean可能发送的每个通知的Java类名和通知类型。

启动JConsole,看到在MBean标签中显示了“通知”节点:

JMX学习笔记(2)_第3张图片

点击右侧的“订阅”按钮,然后修改CacheSize属性,能够获得通知:

JMX学习笔记(2)_第4张图片

注:“用户数据”列为空,是否正常? 构建的Notification对象中的部分信息未显示(如新、旧属性值)。

 

3. MXBean

MXBean是一种特殊的MBean,它使用的数据类型是预定义(pre-defined)的,可以被所有客户端(包括远程客户端)使用。MXBean由一个以“MXBean”为后缀的接口和一个实现类组成,但不要求接口和实现类的名称对应。接口也可以不添加MXBean后缀,而由@MXBean注解标识。

注:

MXBean中的所谓“预定义”的数据类型实际是自定义的,被封装成CompositeDataSupport对象。

示例代码:

/**
 * MXBean接口
 */
public interface QueueSamplerMXBean {
    public QueueSample getQueueSample();
    public void clearQueue();
}

/**
 * MXBean实现
 */
public class QueueSampler implements QueueSamplerMXBean {
    private Queue<String> queue;

    public QueueSampler(Queue<String> queue) {
        this.queue = queue;
    }

    @Override
    public QueueSample getQueueSample() {
        synchronized (queue) {
            return new QueueSample(new Date(), queue.size(), queue.peek());
        }
    }

    @Override
    public void clearQueue() {
        synchronized (queue) {
            queue.clear();
        }
    }
}

/**
 * MXBean中预定义的数据类型
 */
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;
    }

    ...
}

QueueSample类即MXBean的预定义数据类型。

启动JConsole,点击MBean标签,看到MXBean。

JMX学习笔记(2)_第5张图片

注意属性QueueSample的类型为CompositeDataSupport。

双击“属性值”中的“值”列的javax.management.openmbean.CompositeDataSupport,显示详细信息:

JMX学习笔记(2)_第6张图片

进行clearQueue操作后,查看结果:

JMX学习笔记(2)_第7张图片

  

注:

MBean中的各个属性的名称显示全部是首字母大写(不知什么原因)。

 

参考资料:

http://download.oracle.com/javase/6/docs/technotes/guides/jmx/tutorial/tutorialTOC.html

 

to be continued...

你可能感兴趣的:(jmx)