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. }  

現在、nameはHelloWorkShadowとは何の関係もありません.1、2行のコメントを削除すると、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"));
(続き)