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. GetViewUrl

    <f:TemplateField HeaderText="名称" ColumnID="Name" ExpandUnusedSpace="true ...

  2. redis 相关命令

    /etc/init.d/redis-serveredis-cli 进入redis/etc/init.d/redis-server stop /etc/init.d/redis-server start ...

  3. null 和 NULL 判断

    遇到问题,服务器传回 null,我擦嘞,接收不了. 解决如下: NULL 直接 判断就好,能在 xcode 上直接敲出 null 的话  可以  ==[NSNull class] 或者[respons ...

  4. .net利用NPOI导入导出Excel

    NPOI在.net中的操作Excel 1.读取 using (FileStream stream = new FileStream(@"c:\客户资料.xls", FileMode ...

  5. CSS 初体验之Line-height

    p{ line-height:20px; } line-height : normal | length 参数: normal : 默认行高length : 百分比数字 | 由浮点数字和单位标识符组成 ...

  6. find 路径必须在表达式之前

    http://sukaka.blog.51cto.com/379985/906008 把*号引起来.

  7. 关于使用Unity开发Kinect时出现的Runtime Error错误的解决方式

    一.开发环境: 1. 硬件:Kinect 2.0 2. 操作系统:Windows10 3. Unity版本:5.x以上 4. Kinect SDK:KinectSDK-v2.0_1409 5. Kin ...

  8. 关于node

    nodejs npm常用命令 npm是一个node包管理和分发工具,已经成为了非官方的发布node模块(包)的标准.有了npm,可以很快的找到特定服务要使用的包,进行下载.安装以及管理已经安装的包. ...

  9. jQuery与JS中的map()方法使用

    1.jquery中的map()方法 首先看一个简单的实例: $("p").append( $("input").map(function(){ return $ ...

  10. unsupported time zone specified undefined

    unsupported time zone specified undefined   出现了这个问题,莫名其妙的,上次被我下回去了,真的是下回去的,我一去查看,坐在电脑前面问题就不见了…… 具体出现 ...