模型Bean:Model Bean

五柳-先生發表於2015-10-21

在上一節是用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類中的方法邏輯。

轉載: http://www.blogjava.net/hengheng123456789/articles/66579.html

相關文章