JMX之模型MBean

標準MBean所暴露的屬性,操作,通知都是固定不變的,都固化在ClassNameMBean這個接口中,靈活度不足。

動態Mbean所暴露的特性是運行時確立,靈活度足夠,但編碼困難,因爲你需要編碼實現每一個屬性,操作與通知。

模型Mbean也是一種動態Mbean,能夠使你更快的編寫動態MBean.

模型MBean的封裝類RequiredModelMBean實現了ModelMBean接口,ModelMBean接口繼承自DynamicMBean,所以說模型Mbean也是一種動態Mbean

首先定義需要管理的資源:

  1. package guojje.jmx;  
  2.  
  3. import javax.management.NotificationBroadcasterSupport;  
  4.  
  5. public class HelloWordShadow extends NotificationBroadcasterSupport{  
  6.       
  7.     private String name = "anranran";  
  8.     public HelloWordShadow(String name){  
  9.         this.name = name;  
  10.     }  
  11.       
  12.     public String getName(){  
  13.         System.out.println("invoke getName method!!");  
  14.         return name;  
  15.     }  
  16.       
  17.     public void setName(String name){  
  18.         System.out.println("invoke setName method!!");  
  19.         this.name = name;  
  20.     }  
  21.       
  22.     public void Say(){  
  23.         System.out.println("hi~!!!");  
  24.     }  
  25. }  

測試類:

  1. package guojje.jmx;  
  2. public class Main {  
  3.     public static void main(String args[]) throws Exception {  
  4.         JMXServiceURL jUrl = new JMXServiceURL("iiop""192.168.1.61"9998,  
  5.                 "/jndi/rmi://localhost:9999/guojje");  
  6.         MBeanServer ms = MBeanServerFactory.createMBeanServer();  
  7.         JMXConnectorServer cs = JMXConnectorServerFactory  
  8.                 .newJMXConnectorServer(jUrl, null, ms);  
  9.         cs.start();  
  10.         System.out.println("jmx address:" + cs.getAddress());  
  11.  
  12.         exeHelloWordShadow(ms);  
  13.     }  
  14. private static void exeHelloWordShadow(MBeanServer ms) throws Exception {  
  15.         RequiredModelMBean rmm = new RequiredModelMBean();  
  16.         //add a property called 'name'  
  17.         ModelMBeanAttributeInfo nameAttr = new ModelMBeanAttributeInfo("name","java.lang.String",  
  18.                 "pepole name",truetruefalse,null);  
  19.           
  20.         ModelMBeanInfo mmInfo = new ModelMBeanInfoSupport(RequiredModelMBean.class.toString(), "Jmx demo"new ModelMBeanAttributeInfo[]{nameAttr}, nullnullnull);  
  21.         rmm.setModelMBeanInfo(mmInfo);  
  22.     //System.out.println(nameAttr.getDescriptor().getFieldValue("value"));//1  
  23.         rmm.setAttribute(new Attribute("name""guojianjun"));  
  24.         System.out.println(rmm.getAttribute("name"));  
  25.     //System.out.println(nameAttr.getDescriptor().getFieldValue("value")); //2  
  26. }  

目前nameHelloWorkShadow還沒有任何關係,去掉12兩行註釋,你會發現ModelMBeanAttributeInfo的描述子用來存儲了這個值(代碼中,ModelMBeanAttributeInfo的最後一個參數,我設了null,JDK會爲之創建一個默認的描述子)。


 

如何把對MBean的操作轉移動對HelloWordShadow的操作,以達到我們管是資源的目的。

第一步爲ModelMBeanAttributeInfo對像添加get,set方法.

  1. private static void exeHelloWordShadow(MBeanServer ms) throws Exception {  
  2. RequiredModelMBean rmm = new RequiredModelMBean();  
  3.         Method getMethod = HelloWordShadow.class.getMethod("getName",  
  4.                 new Class[] {});  
  5.         Method setMethod = HelloWordShadow.class.getMethod("setName",  
  6.                 new Class[] {String.class});  
  7.         //add a property called 'name'  
  8.         ModelMBeanAttributeInfo nameAttr = new ModelMBeanAttributeInfo("name",  
  9.                 "pepole name",getMethod, setMethod,null);  
  10.           
  11.           
  12.           
  13.         ModelMBeanInfo mmInfo = new ModelMBeanInfoSupport(RequiredModelMBean.class.toString(), "Jmx demo", new ModelMBeanAttributeInfo[]{nameAttr}, null, null, null);  
  14.         rmm.setModelMBeanInfo(mmInfo);  
  15.           
  16.         rmm.setAttribute(new Attribute("name", "guojianjun"));  
  17.         System.out.println(rmm.getAttribute("name"));   

運行結果:

jmx address:service:jmx:iiop://192.168.1.61:9998/jndi/rmi://localhost:9999/guojje

guojianjun

發現並沒有起作用。剛纔說到ModelMBeanAttributeInfo用了默認的描述子,我們不防給

添加一個描述子:

  1. private static void exeHelloWordShadow(MBeanServer ms) throws Exception {  
  2.     .....
  3. Descriptor nameDesc = new DescriptorSupport();  
  4.         nameDesc.setField("name""Name");//must be setted  
  5.         nameDesc.setField("descriptorType""attribute");//must be setted  
  6.         nameDesc.setField("displayName""Name");  
  7.         nameDesc.setField("getMethod""getName");  
  8.         nameDesc.setField("setMethod""setName");  
  9.         //add a property called 'name'  
  10.         ModelMBeanAttributeInfo nameAttr = new ModelMBeanAttributeInfo("name",  
  11.                 "pepole name",getMethod, setMethod,nameDesc);  
  12.           
  13.         ModelMBeanInfo mmInfo = new ModelMBeanInfoSupport(null"Jmx demo"new ModelMBeanAttributeInfo[]{nameAttr}, nullnullnull);  
  14.         rmm.setModelMBeanInfo(mmInfo);  
  15.           
  16.         rmm.setAttribute(new Attribute("name""guojianjun"));  
  17.         System.out.println(rmm.getAttribute("name"));  

更糟糕,直接報錯:Operation setName not in ModelMBeanInfo

但這也說明是用描述子設定set方法是正確的。這樣我們需要在ModelMBeanInfo中聲明setName操作,getName一樣: 

    .....
  1. //add a property called 'name'  
  2.         ModelMBeanAttributeInfo nameAttr = new ModelMBeanAttributeInfo("name",  
  3.                 "pepole name",getMethod, setMethod,nameDesc);  
  4.           
  5.          //parameter is not necessary  
  6.          ModelMBeanOperationInfo getName = new ModelMBeanOperationInfo(//  
  7.                     "getName"//  
  8.                     "get name attribute"//  
  9.                     null//  
  10.                     "java.lang.String"//  
  11.                     MBeanOperationInfo.ACTION, //  
  12.                     null//  
  13.                   );   
  14.            
  15.          MBeanParameterInfo mParam = new MBeanParameterInfo("name""java.lang.String""set name methord param");  
  16.            
  17.          ModelMBeanOperationInfo setName = new ModelMBeanOperationInfo(//  
  18.                     "setName"//  
  19.                     "set name attribute"//  
  20.                     new MBeanParameterInfo[]{mParam}, //  
  21.                     null//  
  22.                     MBeanOperationInfo.ACTION, //  
  23.                     null//  
  24.           );   
  25.           
  26.         ModelMBeanInfo mmInfo = new ModelMBeanInfoSupport(null"Jmx demo"new ModelMBeanAttributeInfo[]{nameAttr},   
  27.                 null , new ModelMBeanOperationInfo[]{getName,setName}, null);  
  28.         rmm.setModelMBeanInfo(mmInfo);  
  29.           
  30.         rmm.setAttribute(new Attribute("name""guojianjun"));  
  31.         System.out.println(rmm.getAttribute("name"));  

仍然報錯: managedResource for invoke setName is null

managedResource是什麼?就是我們需要管理的對像資源,在這裏當然是HelloWordShadow對象,終於扯上關係了。那就構造一個HelloWordShadow對象:

  1. .....
  2. ModelMBeanInfo mmInfo = new ModelMBeanInfoSupport(RequiredModelMBean.class.toString(), "Jmx demo"new ModelMBeanAttributeInfo[]{nameAttr},   
  3.                 null , new ModelMBeanOperationInfo[]{getName,setName}, null);  
  4.         rmm.setModelMBeanInfo(mmInfo);  
  5.           
  6.         HelloWordShadow hw = new HelloWordShadow("miniName");  
  7.         rmm.setManagedResource(hw, "ObjectReference");  
  8.           
  9.         rmm.setAttribute(new Attribute("name""guojianjun"));  
  10.         System.out.println(rmm.getAttribute("name"));  

運行輸出:

jmx address:service:jmx:iiop://192.168.1.61:9998/jndi/rmi://localhost:9999/guojje

invoke getName method!!

invoke setName method!!

invoke getName method!!

guojianjun

OK,成功。說了這麼多,那構造函數ModelMBeanAttributeInfo("name",         "pepole name",getMethod, setMethod,nameDesc);裏的getMethod, setMethod方法有什麼用呢,我覺得好像沒什麼用,只是用來確認屬性類型,可讀可寫情況。(個人觀點)

最後就是把這個MBean註冊到MBeanServer中管理,Jconsole就可以看到了:

ms.registerMBean(rmm, new ObjectName(

       "guojje:type=notification,name=hello"));

(待續)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章