Notification通知,也可理解为消息,有通知,必然有发送通知的广播,JMX这里采用了一种订阅的方式,类似于观察者模式,注册一个观察者到广播里,当有通知时,广播通过调用观察者,逐一通知.

这里写一个简单的Server配置例子, 首先定义我们的MBean接口:

接着,我们会想第一节那样,去实现这个MBean接口,并且继承NotificationBroadcasterSupport,来提供广播服务:

package com.dxz.mbean;

import java.util.concurrent.atomic.AtomicLong;

import javax.management.AttributeChangeNotification;
import javax.management.NotificationBroadcasterSupport; public class ServerConfigure extends NotificationBroadcasterSupport implements ServerConfigureMBean { private AtomicLong sequenceNumber = new AtomicLong(1); private int port; private String host; public void setPort(int port) {
int oldPort = this.port;
this.port = port;
AttributeChangeNotification notification = new AttributeChangeNotification(this,
sequenceNumber.getAndIncrement(), System.currentTimeMillis(),
AttributeChangeNotification.ATTRIBUTE_CHANGE, "Server Port Change", "java.lang.Integer", oldPort + "",
this.port + "");
super.sendNotification(notification);
} public int getPort() {
return port;
} public void setHost(String host) {
String oldHost = this.host;
this.host = host;
AttributeChangeNotification notification = new AttributeChangeNotification(this,
sequenceNumber.getAndIncrement(), System.currentTimeMillis(),
AttributeChangeNotification.ATTRIBUTE_CHANGE, "Server Host Change", "java.lang.String", oldHost,
this.host);
super.sendNotification(notification);
} public String getHost() {
return host;
} }

在setPort与setHos方法中,首先new了一个AttributeChangeNotification,这个类是javax.management.Notification的子类,而javax.management.Notification这个类又是Java.util.EventObject的子类,由此可以证实上边所说的,JMX通知机制使用了观察者设计模式。

javax.management.Notification是一个JMX的通知核心类,将来需要扩展或者其他JMX自带的消息,均集成自此类.

AttributeChangeNotification根据类名可知,是一个属性改变的通知,造方法参数如下:

Object source,                 // 事件源,一直传递到java.util.EventObject的source

long sequenceNumber,   // 通知序号,标识每次通知的计数器

long timeStamp,              // 通知发出的时间戳

String msg,                     // 通知发送的message

String attributeName,     // 被修改属性名

String attributeType,      // 被修改属性类型

Object oldValue,             // 被修改属性修改以前的值

Object newValue            // 被修改属性修改以后的值

根据观察者模式,由事件与广播组成,所以这里继承了NotificationBroadcasterSupport,来提供广播机制,调用NotificationBroadcasterSupportr的sendNotification(notification) 发送广播,广播会根据注册的观察者来对观察者进行逐一通知.

sendNotification 在JDK1.6是通过Executor来发送通知,默认调用线程同步发送:

  1. public NotificationBroadcasterSupport(Executor executor,
    MBeanNotificationInfo... info) {
    this.executor = (executor != null) ? executor : defaultExecutor; notifInfo = info == null ? NO_NOTIFICATION_INFO : info.clone();
    }
private final static Executor defaultExecutor = new Executor() {
// DirectExecutor using caller thread
public void execute(Runnable r) {
r.run();
}
};

如果想用异步发送通知,大家可以在构造方法中传入异步执行的Executor , 例如 ThreadPoolExecutor.

接下来,还得写一个观察者,来接受我们送出的通知:

package com.dxz.mbean;

import javax.management.Notification;
import javax.management.NotificationListener; public class ServerConfigureNotificationListener implements NotificationListener { public void handleNotification(Notification notification, Object handback) {
log("SequenceNumber:" + notification.getSequenceNumber());
log("Type:" + notification.getType());
log("Message:" + notification.getMessage());
log("Source:" + notification.getSource());
log("TimeStamp:" + notification.getTimeStamp());
log("UserData:" + notification.getUserData());
log("========="+notification.toString());
} private void log(String message) {
System.out.println(message);
} }

这里只是简单输出了通知内容, 在这个类中我们实现NotificationListener接口,可以看出该接口中只有一个方法,就是处理消息,顺藤摸瓜,在看一下NotificationListener的接口代码:

package javax.management;   

import java.util.EventListener;   

/**
* Should be implemented by an object that wants to receive notifications.
*
* @since 1.5
*/
public interface NotificationListener extends java.util.EventListener { /**
* Invoked when a JMX notification occurs.
* The implementation of this method should return as soon as possible, to avoid
* blocking its notification broadcaster.
*
* @param notification The notification.
* @param handback An opaque object which helps the listener to associate information
* regarding the MBean emitter. This object is passed to the MBean during the
* addListener call and resent, without modification, to the listener. The MBean object
* should not use or modify the object.
*
*/
public void handleNotification(Notification notification, Object handback) ;
}

可以很清楚的看出继承了java.util.EventListener接口,又一次证实了,JMX通知机制是观察者模式的衍生产品.

好了,所有的功能代码都写完了,下边需要测试一JMX的通知机制:

这里还需要写一个测试用例来支持:

package com.dxz.mbean;

import java.lang.management.ManagementFactory;

import javax.management.MBeanServer;
import javax.management.ObjectName; public class ServerStartup {
public static void main(String[] args) throws Exception {
// 创建MBeanServer
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
// 新建MBean ObjectName, 在MBeanServer里标识注册的MBean
ObjectName name = new ObjectName("com.dxz.mbean.server:type=ServerConfigure");
// 创建MBean
ServerConfigure mbean = new ServerConfigure();
// 在MBeanServer里注册MBean, 标识为ObjectName(com.dxz.mbean.server:type=ServerConfigure)
mbs.registerMBean(mbean, name);
// 自定义观察者
ServerConfigureNotificationListener listener = new ServerConfigureNotificationListener();
// 加入MBeanServer
mbs.addNotificationListener(name, listener, null, null);
Thread.sleep(Long.MAX_VALUE);
}
}

最后,我们开始验证成果:

1.打开%JAVA_HOME%/bin/jconsole连接到本地进程:

2. 进入MBean选项框, 点击左边的树,打开通知:

3. 订阅通知

4. 修改属性,产生通知

5. 验证通知

OK, 学习笔记二写完了,回想下一,

1. JMX中要定义接口必须以xxxMBean的规范定义

2. 得有类实现xxxMBean接口

3. 在实现类中可以继承NotificationBroadcasterSupport来支持通知机制

4. 可以通过jconsole来验证

JMX学习笔记(二)-Notification的更多相关文章

  1. WPF的Binding学习笔记(二)

    原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...

  2. AJax 学习笔记二(onreadystatechange的作用)

    AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...

  3. [Firefly引擎][学习笔记二][已完结]卡牌游戏开发模型的设计

    源地址:http://bbs.9miao.com/thread-44603-1-1.html 在此补充一下Socket的验证机制:socket登陆验证.会采用session会话超时的机制做心跳接口验证 ...

  4. java之jvm学习笔记二(类装载器的体系结构)

    java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...

  5. Java IO学习笔记二

    Java IO学习笔记二 流的概念 在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成. 程序中的输入输 ...

  6. 《SQL必知必会》学习笔记二)

    <SQL必知必会>学习笔记(二) 咱们接着上一篇的内容继续.这一篇主要回顾子查询,联合查询,复制表这三类内容. 上一部分基本上都是简单的Select查询,即从单个数据库表中检索数据的单条语 ...

  7. NumPy学习笔记 二

    NumPy学习笔记 二 <NumPy学习笔记>系列将记录学习NumPy过程中的动手笔记,前期的参考书是<Python数据分析基础教程 NumPy学习指南>第二版.<数学分 ...

  8. Learning ROS for Robotics Programming Second Edition学习笔记(二) indigo tools

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  9. Redis学习笔记二 (BitMap算法分析与BitCount语法)

    Redis学习笔记二 一.BitMap是什么 就是通过一个bit位来表示某个元素对应的值或者状态,其中的key就是对应元素本身.我们知道8个bit可以组成一个Byte,所以bitmap本身会极大的节省 ...

随机推荐

  1. ios Base64编解码工具类及使用

    为了避免明码传递http内容,可以用base64编码后传输,收到方再解码,也方便了2进制数据的字符串式传输. 对于ios来说,google给提供了一个很好的工具类,方便进行base64编解码,当然也可 ...

  2. python学习笔记4(列表)

    列表是最通用的Python复合数据类型,列表中包含以逗号分隔,并在方括号([])包含的项目. 在一定程度上,列表相似C语言中的数组,它们之间的一个区别是,所有属于一个列表中的项目可以是不同的数据类型的 ...

  3. Android Studio 单刷《第一行代码》系列 03 —— Activity 基础

    前情提要(Previously) 本系列将使用 Android Studio 将<第一行代码>(书中讲解案例使用Eclipse)刷一遍,旨在为想入坑 Android 开发,并选择 Andr ...

  4. c#用反射原理递归遍历复杂实体对象

    之前在网上看到的都是遍历那种比较简单的实体对象,但是如果有实体嵌套,甚至是包含有List<XXInfo>这种属性的时候就没有办法处理了.通过递归遍历的方式可以完成对复杂实体对象的所有属性的 ...

  5. oracle-number(5,2)

    insert into emp values(70000.123); 只能存储 整数的前3位, 小数点后面的2位

  6. 用std::thread替换实现boost::thread_group

    thread_group是boost库中的线程池类,内部使用的是boost::thread. 随着C++ 11标准的制定和各大编译器的新版本的推出(其实主要是VS2012的推出啦……),本着能用标准库 ...

  7. openvas

    http://www.freebuf.com/articles/5474.html EPEL http://www.centoscn.com/CentOS/config/2014/0920/3793. ...

  8. zoj 3380 Patchouli's Spell Cards 概率DP

    题意:1-n个位置中,每个位置填一个数,问至少有l个数是相同的概率. 可以转化求最多有l-1个数是相同的. dp[i][j]表示前i个位置填充j个位置的方案数,并且要满足上面的条件. 则: dp[i] ...

  9. redis 参考

    http://redis.readthedocs.org/en/2.4/index.html

  10. java中List集合及其遍历详解

    1. 首先List<E>集合继承与Collection<E>,是一个接口. ①  Collection (集合框架是JDK1.2版本出现的) ②   list:是有序的,元素可 ...