這篇寫一個(gè)簡(jiǎn)單的HelloWorld例子。
首先準(zhǔn)備環(huán)境,我使用的JDK1.6,1.5應(yīng)該也可以。還需要去oracle下載JMX RI包,地址為:http://www.oracle.com/technetwork/java/javase/tech/download-jsp-141676.html,下載“JMX 1.2 Reference Implementation”,解壓以后lib目錄下有兩個(gè)jar包,把jmxtool.jar加到CLASSPATH中就可以了,它里面有一個(gè)接下去要用到的Html適配器。
1、首先寫一個(gè)HelloWorld MBean,它由一個(gè)接口和一個(gè)實(shí)現(xiàn)類組成,代碼如下:
public interface HelloWorldMBean {
public void setGreeting(String greeting);
public String getGreeting();
public void printGreeting();
}
寫實(shí)現(xiàn)類HelloWorld:
public class HelloWorld implements HelloWorldMBean {

private String greeting = null;

public HelloWorld() {
this.greeting = "Hello World! I am a Standard MBean";
}

public HelloWorld(String greeting) {
this.greeting = greeting;
}

public void setGreeting(String greeting) {
this.greeting = greeting;
}

public String getGreeting() {
return greeting;
}

public void printGreeting() {
System.out.println(greeting);
}

}
這樣,一個(gè)HelloWorld的MBean就完成了,這是一個(gè)標(biāo)準(zhǔn)MBean。必須把MBean注冊(cè)到Agent才能使用,接下來寫一個(gè)Agent。
2、定義JMX Agent:HelloAgent,他有三個(gè)任務(wù):
1)、創(chuàng)建MBean Server實(shí)例。
2)、創(chuàng)建HTML適配器和HTML客戶端連接。
3)、注冊(cè)一個(gè)新的HelloWorld的MBean實(shí)例。
代碼如下:
public class HelloAgent {

private MBeanServer mbs = null;

public HelloAgent() {
mbs = MBeanServerFactory.createMBeanServer("HelloAgent");

HtmlAdaptorServer adapter = new HtmlAdaptorServer();
HelloWorld hw = new HelloWorld();
ObjectName adapterName = null;
ObjectName helloWorldName = null;
try {
helloWorldName = new ObjectName("HelloAgent:name=helloWorld1");
mbs.registerMBean(hw, helloWorldName);
adapterName = new ObjectName("HelloAgent:name=htmladapter,port=9092");
adapter.setPort(9092);
mbs.registerMBean(adapter, adapterName);
adapter.start();
} catch (Exception e) {
e.printStackTrace();
}
}

public static void main(String args[]) {
System.out.println("HelloAgent is running");
HelloAgent agent = new HelloAgent();
}
}
這段代碼首先創(chuàng)建一個(gè)MBean Server實(shí)例和一個(gè)Html適配器實(shí)例,MBean Server使用工廠類創(chuàng)建,創(chuàng)建的時(shí)候傳入字符串作為MBean Server的域名,域名是區(qū)別MBean Server的標(biāo)識(shí)。
接下來實(shí)例化HelloWorld MBean,并在MBean Server中注冊(cè)。注冊(cè)的時(shí)候使用一個(gè)ObjectName實(shí)例,ObjectName類在JMX中為MBean提供了一套命名系統(tǒng),是注冊(cè)在MBean Server中的唯一標(biāo)識(shí)。它有兩部分組成:
1)、域名:這個(gè)域名通常和MBean Server的域名一致,如果不一致,則意味著與其他MBean隔離。
2)、零個(gè)或多個(gè)key=value串,中間用逗號(hào)隔開,這個(gè)串用來區(qū)別MBean,也可以為MBean提供信息。
下一步是注冊(cè)Html適配器,Html適配器也是一個(gè)MBean,并啟動(dòng)適配器。
以上兩步就是我們例子的代碼,基本結(jié)構(gòu)圖如下:

3、運(yùn)行例子。HelloAgent類有main方法,直接運(yùn)行就可以了,如果成功就會(huì)出現(xiàn)“HelloAgent is running”。然后打開瀏覽器,輸入:http://localhost:9092/,因?yàn)榇a中Html的適配器端口設(shè)置為9092。
以上3步完成了整個(gè)HelloWorld例子,通過瀏覽器提供了3種頁面:
1、Agent頁面,也就是第一個(gè)看到的頁面,上面Agent內(nèi)包含的MBean的一個(gè)總覽,它顯示了所有的注冊(cè)在里面的MBean,通過注冊(cè)時(shí)候使用的ObjectName實(shí)例來顯示。可以通過最上面的文本框來過濾需要顯示的MBean。
2、MBean頁面,點(diǎn)擊Agent頁面中的某個(gè)MBean可以進(jìn)入該MBean頁面。我們點(diǎn)擊第一個(gè)name=helloWorld1的MBean,顯示有一下幾個(gè)信息:
a)、MBean注冊(cè)時(shí)提供的ObjectName,HelloAgent:name=helloWorld1
b)、類的名字,在這個(gè)例子中是HelloWorld。
c)、描述,對(duì)于Stand MBean,描述有MBean Server創(chuàng)建。
d)、屬性列表,MBean暴露的屬性列表,這個(gè)MBean有一個(gè)屬性Greeting是個(gè)可讀寫屬性(RW,因?yàn)橛術(shù)etter和setter),你可以在Value列的文本框中輸入字符串,點(diǎn)擊Apply,就動(dòng)態(tài)設(shè)置了Greeting的值。
e)、暴露的操作列表,這個(gè)MBean有一個(gè)操作printGreeting,點(diǎn)擊printGreeting按鈕可以調(diào)用該操作,會(huì)顯示”printGreeting Successful“的信息,在控制臺(tái)可以看到打印出了你剛才輸入的Greeting屬性的值。
f)、Reload Period,指的是MBean Server是否要重新實(shí)例化這個(gè)MBean,如果是,多久一次。
g)、Unregister按鈕,反注冊(cè)這個(gè)MBean。
本例中還有一個(gè)MBean,就是Html適配器,因?yàn)樗苍贏gent注冊(cè)了成為一個(gè)MBean.
3、Admin頁面,點(diǎn)擊Agent頁面的Admin按鈕就進(jìn)入了Admin頁面。通過這個(gè)頁面可以增加或者刪除MBean,頁面上有4個(gè)文本框分別如下:
a)、Domain-顯示了當(dāng)前Agent的Domain,
b)、Keys,也就是ObjectName類的屬性串。
c)、Java Class,想創(chuàng)建的MBean的完整類名。
d)、Class Loader,這個(gè)是可選的,其他都是必須的。
在Action選項(xiàng)框下面有一個(gè)Constructors選項(xiàng),如果選了這個(gè),點(diǎn)擊Send Request,就會(huì)顯示MBean的所有構(gòu)造器,可以使用其中的一個(gè)來創(chuàng)建MBean實(shí)例了。
MBean通知
加入通知代碼到HelloWorld的MBean,JMX提供了兩種方法使MBean可以作為其他MBean的監(jiān)聽對(duì)象。第一種是實(shí)現(xiàn)javax.management.NotificationBroadcaster接口,第二種時(shí)繼承javax.management.NotificationBroadcasterSupport類。
實(shí)現(xiàn)接口的好處是你還可以繼承其他類,繼承類的好處是你不需要寫實(shí)現(xiàn)接口的方法代碼。我們選擇使用繼承類的方法,HelloWorld類代碼修改成如下:
public class HelloWorld extends NotificationBroadcasterSupport implements HelloWorldMBean {
public HelloWorld() {
this.greeting = "Hello World! I am a Standard MBean";
}

public HelloWorld(String greeting) {
this.greeting = greeting;
}

public void setGreeting(String greeting) {
this.greeting = greeting;
Notification notification = new Notification("jmxtest.ch02.helloWorld.test", this, -1,
System.currentTimeMillis(), greeting);
sendNotification(notification);
}

public String getGreeting() {
return greeting;
}

public void printGreeting() {
System.out.println(greeting);
}

private String greeting;
}
在setGreeting方法中增加了一些代碼,首先實(shí)例化一個(gè)通知,然后發(fā)送這個(gè)通知,也就是說在greeting屬性設(shè)置的時(shí)候,發(fā)送通知到對(duì)次事件感興趣的對(duì)象。實(shí)例化通話需要5個(gè)參數(shù),第一個(gè)是這個(gè)通知的標(biāo)識(shí)符,第二個(gè)是參數(shù)是通知源,也就是產(chǎn)生通知的MBean,第三個(gè)是個(gè)序列號(hào),第四個(gè)是發(fā)送時(shí)間,第五個(gè)是發(fā)送的消息字符串。
修改HelloAgent,代碼如下:
public class HelloAgent implements NotificationListener {

private MBeanServer mbs = null;

public HelloAgent() {
mbs = MBeanServerFactory.createMBeanServer("HelloAgent");
HtmlAdaptorServer adapter = new HtmlAdaptorServer();
HelloWorld hw = new HelloWorld();
ObjectName adapterName = null;
ObjectName helloWorldName = null;
try {
adapterName = new ObjectName("HelloAgent:name=htmladapter,port=9092");
mbs.registerMBean(adapter, adapterName);
adapter.setPort(9092);
adapter.start();
helloWorldName = new ObjectName("HelloAgent:name=helloWorld1");
mbs.registerMBean(hw, helloWorldName);
hw.addNotificationListener(this, null, null);

} catch (Exception e) {
e.printStackTrace();
}
}

public void handleNotification(Notification notif, Object handback) {
System.out.println("Receiving notification
");
System.out.println(notif.getType());
System.out.println(notif.getMessage());
}

public static void main(String args[]) {
System.out.println("HelloAgent is running");
HelloAgent agent = new HelloAgent();
}
}
在構(gòu)造器中增加了“hw.addNotificationListener(this, null, null);”這行代碼,它就是把HelloAgent加入到HelloWorld MBean的監(jiān)聽列表中。還增加了一個(gè)方法handleNotification,這個(gè)是實(shí)現(xiàn)了NotificationListener接口的方法,當(dāng)HelloWorld Mbean的greeting屬性被設(shè)置的時(shí)候,就會(huì)調(diào)用這個(gè)方法,其實(shí)是很簡(jiǎn)單的一個(gè)觀察者模式。
運(yùn)行這個(gè)例子,修改greeting屬性,點(diǎn)擊Apply,看到控制臺(tái)打印了handleNotification方法中的一些信息。
首先準(zhǔn)備環(huán)境,我使用的JDK1.6,1.5應(yīng)該也可以。還需要去oracle下載JMX RI包,地址為:http://www.oracle.com/technetwork/java/javase/tech/download-jsp-141676.html,下載“JMX 1.2 Reference Implementation”,解壓以后lib目錄下有兩個(gè)jar包,把jmxtool.jar加到CLASSPATH中就可以了,它里面有一個(gè)接下去要用到的Html適配器。
1、首先寫一個(gè)HelloWorld MBean,它由一個(gè)接口和一個(gè)實(shí)現(xiàn)類組成,代碼如下:





寫實(shí)現(xiàn)類HelloWorld:

























這樣,一個(gè)HelloWorld的MBean就完成了,這是一個(gè)標(biāo)準(zhǔn)MBean。必須把MBean注冊(cè)到Agent才能使用,接下來寫一個(gè)Agent。
2、定義JMX Agent:HelloAgent,他有三個(gè)任務(wù):
1)、創(chuàng)建MBean Server實(shí)例。
2)、創(chuàng)建HTML適配器和HTML客戶端連接。
3)、注冊(cè)一個(gè)新的HelloWorld的MBean實(shí)例。
代碼如下:




























這段代碼首先創(chuàng)建一個(gè)MBean Server實(shí)例和一個(gè)Html適配器實(shí)例,MBean Server使用工廠類創(chuàng)建,創(chuàng)建的時(shí)候傳入字符串作為MBean Server的域名,域名是區(qū)別MBean Server的標(biāo)識(shí)。
接下來實(shí)例化HelloWorld MBean,并在MBean Server中注冊(cè)。注冊(cè)的時(shí)候使用一個(gè)ObjectName實(shí)例,ObjectName類在JMX中為MBean提供了一套命名系統(tǒng),是注冊(cè)在MBean Server中的唯一標(biāo)識(shí)。它有兩部分組成:
1)、域名:這個(gè)域名通常和MBean Server的域名一致,如果不一致,則意味著與其他MBean隔離。
2)、零個(gè)或多個(gè)key=value串,中間用逗號(hào)隔開,這個(gè)串用來區(qū)別MBean,也可以為MBean提供信息。
下一步是注冊(cè)Html適配器,Html適配器也是一個(gè)MBean,并啟動(dòng)適配器。
以上兩步就是我們例子的代碼,基本結(jié)構(gòu)圖如下:

3、運(yùn)行例子。HelloAgent類有main方法,直接運(yùn)行就可以了,如果成功就會(huì)出現(xiàn)“HelloAgent is running”。然后打開瀏覽器,輸入:http://localhost:9092/,因?yàn)榇a中Html的適配器端口設(shè)置為9092。
以上3步完成了整個(gè)HelloWorld例子,通過瀏覽器提供了3種頁面:
1、Agent頁面,也就是第一個(gè)看到的頁面,上面Agent內(nèi)包含的MBean的一個(gè)總覽,它顯示了所有的注冊(cè)在里面的MBean,通過注冊(cè)時(shí)候使用的ObjectName實(shí)例來顯示。可以通過最上面的文本框來過濾需要顯示的MBean。
2、MBean頁面,點(diǎn)擊Agent頁面中的某個(gè)MBean可以進(jìn)入該MBean頁面。我們點(diǎn)擊第一個(gè)name=helloWorld1的MBean,顯示有一下幾個(gè)信息:
a)、MBean注冊(cè)時(shí)提供的ObjectName,HelloAgent:name=helloWorld1
b)、類的名字,在這個(gè)例子中是HelloWorld。
c)、描述,對(duì)于Stand MBean,描述有MBean Server創(chuàng)建。
d)、屬性列表,MBean暴露的屬性列表,這個(gè)MBean有一個(gè)屬性Greeting是個(gè)可讀寫屬性(RW,因?yàn)橛術(shù)etter和setter),你可以在Value列的文本框中輸入字符串,點(diǎn)擊Apply,就動(dòng)態(tài)設(shè)置了Greeting的值。
e)、暴露的操作列表,這個(gè)MBean有一個(gè)操作printGreeting,點(diǎn)擊printGreeting按鈕可以調(diào)用該操作,會(huì)顯示”printGreeting Successful“的信息,在控制臺(tái)可以看到打印出了你剛才輸入的Greeting屬性的值。
f)、Reload Period,指的是MBean Server是否要重新實(shí)例化這個(gè)MBean,如果是,多久一次。
g)、Unregister按鈕,反注冊(cè)這個(gè)MBean。
本例中還有一個(gè)MBean,就是Html適配器,因?yàn)樗苍贏gent注冊(cè)了成為一個(gè)MBean.
3、Admin頁面,點(diǎn)擊Agent頁面的Admin按鈕就進(jìn)入了Admin頁面。通過這個(gè)頁面可以增加或者刪除MBean,頁面上有4個(gè)文本框分別如下:
a)、Domain-顯示了當(dāng)前Agent的Domain,
b)、Keys,也就是ObjectName類的屬性串。
c)、Java Class,想創(chuàng)建的MBean的完整類名。
d)、Class Loader,這個(gè)是可選的,其他都是必須的。
在Action選項(xiàng)框下面有一個(gè)Constructors選項(xiàng),如果選了這個(gè),點(diǎn)擊Send Request,就會(huì)顯示MBean的所有構(gòu)造器,可以使用其中的一個(gè)來創(chuàng)建MBean實(shí)例了。
MBean通知
加入通知代碼到HelloWorld的MBean,JMX提供了兩種方法使MBean可以作為其他MBean的監(jiān)聽對(duì)象。第一種是實(shí)現(xiàn)javax.management.NotificationBroadcaster接口,第二種時(shí)繼承javax.management.NotificationBroadcasterSupport類。
實(shí)現(xiàn)接口的好處是你還可以繼承其他類,繼承類的好處是你不需要寫實(shí)現(xiàn)接口的方法代碼。我們選擇使用繼承類的方法,HelloWorld類代碼修改成如下:


























在setGreeting方法中增加了一些代碼,首先實(shí)例化一個(gè)通知,然后發(fā)送這個(gè)通知,也就是說在greeting屬性設(shè)置的時(shí)候,發(fā)送通知到對(duì)次事件感興趣的對(duì)象。實(shí)例化通話需要5個(gè)參數(shù),第一個(gè)是這個(gè)通知的標(biāo)識(shí)符,第二個(gè)是參數(shù)是通知源,也就是產(chǎn)生通知的MBean,第三個(gè)是個(gè)序列號(hào),第四個(gè)是發(fā)送時(shí)間,第五個(gè)是發(fā)送的消息字符串。
修改HelloAgent,代碼如下:




































在構(gòu)造器中增加了“hw.addNotificationListener(this, null, null);”這行代碼,它就是把HelloAgent加入到HelloWorld MBean的監(jiān)聽列表中。還增加了一個(gè)方法handleNotification,這個(gè)是實(shí)現(xiàn)了NotificationListener接口的方法,當(dāng)HelloWorld Mbean的greeting屬性被設(shè)置的時(shí)候,就會(huì)調(diào)用這個(gè)方法,其實(shí)是很簡(jiǎn)單的一個(gè)觀察者模式。
運(yùn)行這個(gè)例子,修改greeting屬性,點(diǎn)擊Apply,看到控制臺(tái)打印了handleNotification方法中的一些信息。