http://www.blogjava.net/hengheng123456789/articles/66095.html
Mbean之间的通信是必不可少的,Notification就起到了在Mbean之间沟通桥梁的作用。JMX notification 由四部分组成:
* Notification 这个相当于一个信息包,封装了需要传递的信息
* Notification broadcaster 这相当于一个广播器,把消息广播出去
* Notification listerner 这是一个监听器,用于监听广播出来的Notification消息
* Notification filter 这是一个过滤器,过滤掉不需要的Notification消息
Notification broadcaster不需要我们实现,JMX的内部已经有了。Notification filter一般也很少用。下面的例子主要用到了Notification、Notification listerner。
public interface JackMBean {
void hi();
}
/**
* 必需继承NotificationBroadcasterSupport
* 此类只有一个hi方法,方法只有两句:创建一个Notification消息包,然后将包发出去
* 如果你还要在消息包上附加其他数据,Notification还有一个setUserData方法可供使用
*/
public class Jack extends NotificationBroadcasterSupport implements JackMBean {
private int seq = 0;
@Override
public void hi() {
Notification n = new Notification(//创建一个信息包
"jack.hi",//给这个Notification起个名称
this, //由谁发出的Notification
++seq,//一系列通知中的序列号,可以设任意数值
System.currentTimeMillis(),//发出时间
"Jack");//发出的消息文本
//发出去
sendNotification(n);
}
}
public class HelloListener implements NotificationListener {
public void handleNotification(Notification n, Object handback) {
System.out.println("type=" + n.getType());
System.out.println("source=" + n.getSource());
System.out.println("seq=" + n.getSequenceNumber());
System.out.println("send time=" + n.getTimeStamp());
System.out.println("message=" + n.getMessage());
if (handback != null) {
if (handback instanceof HelloWorld) {
HelloWorld hello = (HelloWorld) handback;
hello.printHello(n.getMessage());
}
}
}
}
public class HelloNotifyAgent {
public static void main (String args[]) throws Exception{
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
ObjectName helloName = new ObjectName("HelloAgent:name=HelloWorld");
HelloWorld hello=new HelloWorld();
server.registerMBean(hello, helloName);
ObjectName adapterName = new ObjectName("HelloAgent:name=htmlAdapter");
HtmlAdaptorServer adapter = new HtmlAdaptorServer();
server.registerMBean(adapter, adapterName);
Jack jack = new Jack();
server.registerMBean(jack, new ObjectName("HelloAgent:name=jack"));
jack.addNotificationListener(new HelloListener(), null, hello);
adapter.start();
System.out.println("start.....");
}
}
Notification和Java的事件模型是一样的,另外如果你买了《Eclipse从入门到精通》,你会发现第22.4节也使用了和Notification和Java的事件模型相同的设计方式。Notification在我们的实际项目中也用到了,象我们现在的给移动做的项目中(基于JMX实现),分散在各地方的工作站的日志,就是通过Notification方式,把每条产生的日志封装在 Notification中实时发回主控服务器的。有机会我会发这一系统的关于日志的设计方案写一下,它实现了对各地工作站的集中的、实时的监控,非常实用。
another example
public interface HelloMBean {
void sayHello();
int add(int x, int y);
String getName();
int getCacheSize();
void setCacheSize(int size);
}
/**
* 要生成通知,MBean必须实现NotificationEmitter接口或
* 继承NotificationBroadcasterSupport类。
* 要发送一个通知必须构造Notification类的实例
* 或者子类(如NotificationChangedAttribute),通知实例产生后,
* 由NotificationBroadcasterSupport的sendNotification方法发送通知。
*/
public class Hello extends NotificationBroadcasterSupport implements HelloMBean {
private final String name = "Reginald";
private int cacheSize = DEFAULT_CACHE_SIZE;
private static final int DEFAULT_CACHE_SIZE = 200;
private long sequenceNumber = 1;
public void sayHello() {
System.out.println("hello, world");
}
public int add(int x, int y) {
return x + y;
}
public String getName() {
return this.name;
}
public int getCacheSize() {
return this.cacheSize;
}
public synchronized void setCacheSize(int size) {
int oldSize = this.cacheSize;
this.cacheSize = size;
System.out.println("Cache size now " + this.cacheSize);
/**
* To send a notification,you need to construct an instance of class
* Notification or a Subclass(such as AttributeChangedNotification),and
* pass the instance to NotificationBroadcastSupport.sendNotification.
*
*/
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 name = AttributeChangeNotification.class.getName();
String description = "An attribute of this MBean has changed";
MBeanNotificationInfo info = new MBeanNotificationInfo(types, name,
description);
return new MBeanNotificationInfo[] { info };
}
}
public class MBeanRun {
public static void main(String[] args) throws Exception{
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName name = new ObjectName("com.jmx.demo:type=Hello");
Hello mbean = new Hello();
mbs.registerMBean(mbean, name);
System.out.println("Waiting forever...");
Thread.sleep(Long.MAX_VALUE);
}
}
getNotificationInfo方法的作用,暂时只知道会让“”通知“”多一个子节点: