一、簡介
Mbean之間的通信是必不可少的,Notification就起到了在Mbean之間溝通橋梁的作用。JMX notification 由四部分組成:
??? * Notification 這個相當于一個信息包,封裝了需要傳遞的信息
??? * Notification broadcaster 這相當于一個廣播器,把消息廣播出去
??? * Notification listerner 這是一個監(jiān)聽器,用于監(jiān)聽廣播出來的Notification消息
??? * Notification filter 這是一個過濾器,過濾掉不需要的Notification消息
Notification broadcaster不需要我們實現(xiàn),JMX的內(nèi)部已經(jīng)有了。Notification filter一般也很少用。下面的例子主要用到了Notification、Notification listerner。
二、實例
在第一篇的Hello中有一個printHello(String whoName)方法,意思根據(jù)碰到的是誰來打招呼,比如:
?
Jack從對面走過來,說:“hi”
我們回之以禮,說:“Hello, jack”
首先這需要Jack先說一個hi(相應(yīng)一個操作方法),然后他說的話封裝成聲波(相當Notification消息包)傳遞出去。然后我們還要給Jakc裝上一個監(jiān)聽器(Hello的耳朵??^_^),這個監(jiān)聽器將捕捉到Jack的聲波語音包,并進行相應(yīng)處理,即說“Hello, jack”。
好,我們看看如何實現(xiàn)的:
1、Jack類及其相應(yīng)的MBean
?
?? 我們把Jack寫成一個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)建一個信息包
??????????????? "jack.hi",//給這個Notification起個名稱
??????????????? this, //由誰發(fā)出的Notification
??????????????? ++seq,//一系列通知中的序列號,可以設(shè)任意數(shù)值
??????????????? System.currentTimeMillis(),//發(fā)出時間
??????????????? "Jack");//發(fā)出的消息文本
??????? //發(fā)出去
??????? sendNotification(n);
??? }
}
?
?說明:
??? * 必需繼承NotificationBroadcasterSupport
??? * 此類只有一個hi方法,方法只有兩句:創(chuàng)建一個Notification消息包,然后將包發(fā)出去
??? * 如果你還要在消息包上附加其他數(shù)據(jù),Notification還有一個setUserData方法可供使用
2、接下來是他的MBean
public interface JackMBean {
??? public void hi();
}
?
3、創(chuàng)建一個Listener,監(jiān)聽到的Notification消息包將由此類負責(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.....");
??? }
}
?
三、運行
1、先運行HelloAgent啟動服務(wù),再打開瀏覽器輸入網(wǎng)址:http://localhost:8082/
?
2、 進入“name=jack”項,然后單擊“hi”按鈕來執(zhí)行它。這時Eclipse的console視圖
四、總結(jié)
Notification和Java的事件模型是一樣的,另外如果你買了《Eclipse從入門到精通》,你會發(fā)現(xiàn)第22.4節(jié)也使用了和Notification和Java的事件模型相同的設(shè)計方式。Notification在我們的實際項目中也用到了,象我們現(xiàn)在的給移動做的項目中(基于JMX實現(xiàn)),分散在各地方的工作站的日志,就是通過Notification方式,把每條產(chǎn)生的日志封裝在 Notification中實時發(fā)回主控服務(wù)器的。有機會我會發(fā)這一系統(tǒng)的關(guān)于日志的設(shè)計方案寫一下,它實現(xiàn)了對各地工作站的集中的、實時的監(jiān)控,非常實用。