在上一節是用apache的commons-modeler來開發的一個model,只不過commons-modeler幫助我們實現了很多的代碼,而我們只需要寫描述XML文件就行了。這一節,來一個實打實的Model Bean,不借助任何第三方工具包。例子還是沿用Hello這個類,以便于和以前的實現相比較。
一、Model MBean實例
1、Hello.java還是和以前的一樣。這里它沒有再加上一個MBean接口了,只是一個很普通的類。
public class Hello{
??? private String name;
??? public String getName() {
??????? return name;
??? }
??? public void setName(String name) {
??????? this.name = name;
??? }
??? public void printHello() {
??????? System.out.println("Hello World, " + name);
??? }
??? public void printHello(String whoName) {
??????? System.out.println("Hello , " + whoName);
??? }
}
2、接下來是HelloAgent的寫法,和以前就差一句:把“new Hello()”這一句刪除了,加上了ModelMbeanUtils.createModlerMbean();
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import javax.management.modelmbean.RequiredModelMBean;
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();
??????? RequiredModelMBean hello = ModelMBeanUtils.createModlerMBean();
??????? server.registerMBean(hello, helloName);
??????? ObjectName adapterName = new ObjectName("HelloAgent:name=htmladapter,port=8082");
??????? HtmlAdaptorServer adapter = new HtmlAdaptorServer();
??????? server.registerMBean(adapter, adapterName);
??????? adapter.start();
??????? System.out.println("start.....");
??? }
}
?
3、ModelMbeanUtils這個類是要我們自己來實現的,也是寫model Bean最麻煩的地方,它主要是返回一個RequiredModelMBean類,此類主要包括了一個ModelMBeanInfo類的信息。在 ModelMBeanInfo中定義了所有對需要管理的屬性和方法的描述。具體代碼如下:
import javax.management.Descriptor;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanParameterInfo;
import javax.management.modelmbean.DescriptorSupport;
import javax.management.modelmbean.ModelMBeanAttributeInfo;
import javax.management.modelmbean.ModelMBeanInfo;
import javax.management.modelmbean.ModelMBeanInfoSupport;
import javax.management.modelmbean.ModelMBeanOperationInfo;
import javax.management.modelmbean.RequiredModelMBean;
public class ModelMBeanUtils {
??? private static final boolean READABLE = true;
??? private static final boolean WRITABLE = true;
??? private static final boolean BOOLEAN = true;
??? private static final String STRING_CLASS = "java.lang.String";
??? public static RequiredModelMBean createModlerMBean() {
??????? RequiredModelMBean model = null;
??????? try {
??????????? model = new RequiredModelMBean();
??????????? model.setManagedResource(new Hello(), "ObjectReference");
??????????? ModelMBeanInfo info = createModelMBeanInfo();
??????????? model.setModelMBeanInfo(info);
??????? } catch (Exception e) {
??????????? e.printStackTrace();
??????? }
??????? return model;
??? }
??? private static ModelMBeanInfo createModelMBeanInfo() {
??????? //////////////////////////////////////////////////////////////////
??????? //??????????????????????? 屬性??????????????????????????????????????? //
??????? //////////////////////////////////////////////////////////////////
??????? // 構造name屬性信息
????????Descriptor portAttrDesc = new DescriptorSupport();
????????portAttrDesc.setField("name", "Name");
????????portAttrDesc.setField("descriptorType", "attribute");
????????portAttrDesc.setField("displayName", "Name");
????????portAttrDesc.setField("getMethod", "getName");
????????portAttrDesc.setField("setMethod", "setName");
??????? ModelMBeanAttributeInfo nameAttrInfo = new ModelMBeanAttributeInfo(//
??????????????? "Name", // 屬性名????? ?
??????????????? STRING_CLASS, //屬性類型?? ?
??????????????? "people name", // 描述文字???? ?
??????????????? READABLE, WRITABLE, !BOOLEAN, // 讀寫???? ?
??????????????? portAttrDesc // 屬性描述子
??????? );
??????? //////////////////////////////////////////////////////////////////
??????? //??????????????????????? 方法??????????????????????????????????????? //
??????? //////////////////////////////////////////////////////////////////
????????// 構造 getName操作描述符信息
????????Descriptor getStateDesc = new DescriptorSupport(new String[] {
??????????"name=getName", "descriptorType=operation", "class=Hello",
??????????"role=operation" });
????????ModelMBeanOperationInfo getName = new ModelMBeanOperationInfo(//
??????????"getName", //
??????????"get name attribute", //
??????????null, //
??????????"java.lang.String", //
??????????MBeanOperationInfo.ACTION, //
??????????getStateDesc //
????????);
????????// 構造 setName操作描述符信息
????????Descriptor setStateDesc = new DescriptorSupport(new String[] {
??????????"name=setName", "descriptorType=operation", "class=Hello",
??????????"role=operation" });
????????MBeanParameterInfo[] setStateParms = new MBeanParameterInfo[] { (new MBeanParameterInfo(
??????????"name", "java.lang.String", "new name value")) };
????????ModelMBeanOperationInfo setName = new ModelMBeanOperationInfo(//
??????????"setName", //
??????????"set name attribute", //
??????????setStateParms, //
??????????"void", //
??????????MBeanOperationInfo.ACTION, //
??????????setStateDesc //
????????);
??????? //構造 printHello()操作的信息????? ?
??????? ModelMBeanOperationInfo print1Info = new ModelMBeanOperationInfo(//
??????????????? "printHello", //
??????????????? null, // ?
??????????????? null, //
??????????????? "void", // ?
??????????????? MBeanOperationInfo.INFO, //?? ?
??????????????? null //
??????? );
??????? // 構造printHello(String whoName)操作信息??? ?
??????? ModelMBeanOperationInfo print2Info;
??????? MBeanParameterInfo[] param2 = new MBeanParameterInfo[1];
??????? param2[0] = new MBeanParameterInfo("whoName", STRING_CLASS, "say hello to who");
??????? print2Info = new ModelMBeanOperationInfo(//
??????????????? "printHello", //
??????????????? null,//
??????????????? param2,//
??????????????? "void", //
??????????????? MBeanOperationInfo.INFO, //
??????????????? null//
??????? );
??????? //////////////////////////////////////////////////////////////////
??????? //??????????????????????? 最后總合??????????????????????????????????? //
??????? //////////////////////////////////////////////////////////////////
??????? // create ModelMBeanInfo????? ?
??????? ModelMBeanInfo mbeanInfo = new ModelMBeanInfoSupport(//
??????????????? RequiredModelMBean.class.getName(), // MBean類
??????????????? null, // 描述文字??? ?
??????????????? new ModelMBeanAttributeInfo[] { // 所有的屬性信息(數組)
??????????????? nameAttrInfo },//只有一個屬性
??????????????? null, // 所有的構造函數信息 ?
??????????????? new ModelMBeanOperationInfo[] { // 所有的操作信息(數組)
????????????????????????getName,?
????????????????????????setName,
??????????????????????? print1Info,
??????????????????????? print2Info },//
??????????????? null, // 所有的通知信息(本例無)
??????????????? null//MBean描述子
??????? );
??????? return mbeanInfo;
??? }
}
?
4、看效果的方法和以前一樣,運行HelloAgent,用瀏覽器打開:http://localhost:8082 。效果圖和standard mbean一樣,就不再帖出來了,去第一篇去看吧http://blog.sohu.com/members/somebody076/545896.html
?
二、總結
?? 我們發現模型Mbean(Model MBean)要比標準MBean(standard mbean)復雜多了,那有什么理由讓我們選擇使用模型MBean嗎?我認為,最大的理由就是模型MBean可以動態配置。試想一下這個應用場景:由于安全或其他原因,系統要把某個MBean公開的可管理方法隱藏起來。這時,如果你是用標準MBean,這需要修改接口類,然后重新編譯發布;如果用 Apache commons-modeler來寫的模型MBean,則只需要修改XML文件就行了,不需要重新編譯發布(可能要重啟一下系統)。這就是模型Mbean 優勢之所在了。
細心的人會發現動態MBean和這一節的模型Mbean非常相似,但它們還是有很大不同的:動態MBean沒有Hello類,它要自己實現Hello類中的方法邏輯。