一、簡(jiǎn)介
Mbean之間的通信是必不可少的,Notification就起到了在Mbean之間溝通橋梁的作用。JMX notification 由四部分組成:
- Notification 這個(gè)相當(dāng)于一個(gè)信息包,封裝了需要傳遞的信息
- Notification broadcaster 這相當(dāng)于一個(gè)廣播器,把消息廣播出去
- Notification listerner 這是一個(gè)監(jiān)聽(tīng)器,用于監(jiān)聽(tīng)廣播出來(lái)的Notification消息
- Notification filter 這是一個(gè)過(guò)濾器,過(guò)濾掉不需要的Notification消息
Notification broadcaster不需要我們實(shí)現(xiàn),JMX的內(nèi)部已經(jīng)有了。Notification filter一般也很少用。下面的例子主要用到了Notification、Notification listerner。
二、實(shí)例
在第一篇的Hello中有一個(gè)printHello(String whoName)方法,意思根據(jù)碰到的是誰(shuí)來(lái)打招呼,比如:
Jack從對(duì)面走過(guò)來(lái),說(shuō):“hi”
我們回之以禮,說(shuō):“Hello, jack”
首先這需要Jack先說(shuō)一個(gè)hi(相應(yīng)一個(gè)操作方法),然后他說(shuō)的話封裝成聲波(相當(dāng)Notification消息包)傳遞出去。然后我們還要給Jakc裝上一個(gè)監(jiān)聽(tīng)器(Hello的耳朵??^_^),這個(gè)監(jiān)聽(tīng)器將捕捉到Jack的聲波語(yǔ)音包,并進(jìn)行相應(yīng)處理,即說(shuō)“Hello, jack”。
好,我們看看如何實(shí)現(xiàn)的:
1、Jack類及其相應(yīng)的MBean
我們把Jack寫(xiě)成一個(gè)MBean,如下:
import javax.management.Notification;
import javax.management.NotificationBroadcasterSupport;
public class Jack extends NotificationBroadcasterSupport implements JackMBean {
private int seq = 0;
public void hi() {
Notification n = new Notification(//創(chuàng)建一個(gè)信息包
"jack.hi",//給這個(gè)Notification起個(gè)名稱
this, //由誰(shuí)發(fā)出的Notification
++seq,//一系列通知中的序列號(hào),可以設(shè)任意數(shù)值
System.currentTimeMillis(),//發(fā)出時(shí)間
"Jack");//發(fā)出的消息文本
//發(fā)出去
sendNotification(n);
}
}
說(shuō)明:
- 必需繼承NotificationBroadcasterSupport
- 此類只有一個(gè)hi方法,方法只有兩句:創(chuàng)建一個(gè)Notification消息包,然后將包發(fā)出去
- 如果你還要在消息包上附加其他數(shù)據(jù),Notification還有一個(gè)setUserData方法可供使用
public interface JackMBean {
public void hi();
}
3、創(chuàng)建一個(gè)Listener,監(jiān)聽(tīng)到的Notification消息包將由此類負(fù)責(zé)處理。
import javax.management.Notification;
import javax.management.NotificationListener;
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 Hello) {
Hello hello = (Hello) handback;
hello.printHello(n.getMessage());
}
}
}
}
4、修改HelloAgent如下(加上了紅色的三句):
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import com.sun.jdmk.comm.HtmlAdaptorServer;
public class HelloAgent {
public static void main(String args[]) throws Exception{
MBeanServer server = MBeanServerFactory.createMBeanServer();
ObjectName helloName = new ObjectName("chengang:name=HelloWorld");
Hello hello=new Hello();
server.registerMBean(hello, helloName);
ObjectName adapterName = new ObjectName("HelloAgent:name=htmladapter,port=8082");
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.....");
}
}
三、運(yùn)行
2、 進(jìn)入“name=jack”項(xiàng),然后單擊“hi”按鈕來(lái)執(zhí)行它。這時(shí)Eclipse的console視圖顯示如下:
四、總結(jié)
Notification和Java的事件模型是一樣的,另外如果你買(mǎi)了《Eclipse從入門(mén)到精通》,你會(huì)發(fā)現(xiàn)第22.4節(jié)也使用了和Notification和Java的事件模型相同的設(shè)計(jì)方式。Notification在我們的實(shí)際項(xiàng)目中也用到了,象我們現(xiàn)在的給移動(dòng)做的項(xiàng)目中(基于JMX實(shí)現(xiàn)),分散在各地方的工作站的日志,就是通過(guò)Notification方式,把每條產(chǎn)生的日志封裝在Notification中實(shí)時(shí)發(fā)回主控服務(wù)器的。有機(jī)會(huì)我會(huì)發(fā)這一系統(tǒng)的關(guān)于日志的設(shè)計(jì)方案寫(xiě)一下,它實(shí)現(xiàn)了對(duì)各地工作站的集中的、實(shí)時(shí)的監(jiān)控,非常實(shí)用。
作者簡(jiǎn)介
陳剛,廣西桂林人,著作有《Eclipse從入門(mén)到精通》
您可以通過(guò)其博客了解更多信息和文章:http://www.chenGang.com.cn