<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 12, 文章 - 0, 評論 - 22, 引用 - 0
    數(shù)據(jù)加載中……

    JMX分析1-MBean的實現(xiàn)

          本文只是JDK7中JMX在本地,MBeanServer管理MBeans的默認實現(xiàn)的探索學習,沒有涉及JMX Remote。
          JMX 使用了 Java Bean 模式來傳遞信息。一般說來,JMX 使用有名的 MBean,其內(nèi)部包含了數(shù)據(jù)信息,這些信息可能是:應用程序配置信息、模塊信息、系統(tǒng)信息、統(tǒng)計信息等。另外,MBean 也可以設立可讀寫的屬性、直接操作某些函數(shù)甚至啟動 MBean 可發(fā)送的 notification 等。MBean 包括 Standard,MXBean,Dynamic,Model,Open 等幾種分類,其中最簡單是標準 MBean 和 MXBean,而我們使用得最多的也是這兩種。MXBean 主要是 java.lang.management使用較多,將在下一節(jié)中介紹。我們先了解其他一些重要的 MBean 的種類。

    StandardMBean
         MXBean 規(guī)定了標準 MBean 也要實現(xiàn)一個接口,所有向外界公開的方法都要在這個接口中聲明。否則,管理系統(tǒng)就不能從中獲得相應的信息。此外,該接口的名字也有一定的規(guī)范:即在標準 MBean 類名之后加上“MBean”后綴。若 MBean 的類名叫做 MBeansName 的話,對應的接口就要叫做 MBeansNameMBean。
    例子:
     1 package test.jmx;
     2 
     3 import javax.management.Notification;
     4 import javax.management.NotificationBroadcasterSupport;
     5 
     6 
     7 /**
     8  * 此標準MBean需實現(xiàn)XXXMBean這樣名稱的借口,XXX為這個類的名稱,
     9  * 如果MBean需要消息事件的發(fā)送、監(jiān)聽等需要實現(xiàn)
    10  *  @see javax.management.NotificationBroadcaster,
    11  * 或者繼承@see javax.management.NotificationBroadcasterSupport
    12 
    13  */
    14 public class HelloWorld extends NotificationBroadcasterSupport implements HelloWorldMBean {
    15     public String hello;
    16     
    17     private long seq = 0l;
    18 
    19     public HelloWorld() {
    20         this.hello = "Hello World! I am a Standard MBean";
    21     }
    22 
    23     public HelloWorld(String hello) {
    24         this.hello = hello;
    25     }
    26 
    27     public String getHello() {
    28         return hello;
    29     }
    30 
    31     @Override
    32     public Object getInstance() {
    33         return new Object();
    34     }
    35 
    36     /* 
    37      * 當執(zhí)行message的時候,發(fā)送一個消息(事件)
    38      * @see test.jmx.HelloWorldMBean#message(java.lang.String)
    39      */
    40     @Override
    41     public String message(String ms) {
    42         Notification notice = new  Notification("type1",this,seq++," the message metheod is invoked,the argument ms: "+ms);
    43         sendNotification(notice);
    44         return " the message :  ";
    45     }
    46 
    47     @Override
    48     public void setHello(String hello) {
    49         this.hello = hello;
    50     }
    51 }
    52 

     1 
     2 package test.jmx;
     3 
     4 public interface HelloWorldMBean {
     5     public String getHello();
     6     
     7     public void setHello(String hello);
     8     
     9     public Object getInstance();
    10     
    11     public String message(String ms);
    12 
    13 }
    14 

    測試 :
      1 package test.jmx;
      2 
      3 import java.util.Set;
      4 
      5 import javax.management.Attribute;
      6 import javax.management.MBeanOperationInfo;
      7 import javax.management.MBeanServer;
      8 import javax.management.MBeanServerFactory;
      9 import javax.management.Notification;
     10 import javax.management.NotificationListener;
     11 import javax.management.ObjectInstance;
     12 import javax.management.ObjectName;
     13 import javax.management.modelmbean.RequiredModelMBean;
     14 
     15 import org.junit.Test;
     16 
     17 public class JmxTest {
     18     
     19     /**
     20      * 測試標準MBean
     21      * 需要被管理的方法、屬性等在接口中定義好,創(chuàng)建一個類,繼承此接口,然后實現(xiàn)時候方法, 
     22      * 這樣,但注冊到MBeanServer的時候,會自動管理其,接口中的各個屬性、方法。
     23      * @throws Exception
     24      */
     25     @Test
     26     public void test1StandardMBean() throws Exception{
     27 //        MBeanServer ms = MBeanServerFactory.createMBeanServer("JMX2Test");
     28         MBeanServer ms = MBeanServerFactory.createMBeanServer();
     29         ObjectName name = new ObjectName("Hello:type=myfirstMbean");
     30         
     31 //        ms.createMBean("HelloWorld", objectName);
     32         HelloWorld hello = new HelloWorld(" yao yao , qie ke nao ");
     33         
     34         //MBean需要實現(xiàn)NotificationBroadcaster接口,支持各種事件的發(fā)送和處理
     35         hello.addNotificationListener(new NotificationListener() {
     36             @Override
     37             public void handleNotification(Notification notification, Object handback) {
     38                 System.out.println(" access listen : "+notification);
     39             }
     40         },null,null);
     41         
     42         ms.registerMBean(hello,name );
     43         
     44         String s1 = (String)ms.getAttribute(name, "Hello");
     45         System.out.println(" the init value : "+s1);
     46         
     47         ms.setAttribute(name, new Attribute("Hello"," hi ,hi ,man "));
     48         String s2 = (String)ms.getAttribute(name, "Hello");
     49         System.out.println(" the init value : "+s2);
     50         
     51         ms.invoke(name, "message", new Object[]{" i as message "}, new String[]{"java.lang.String"});
     52 
     53         ObjectName name2 = new ObjectName("*:*");
     54         Set<ObjectInstance> set = ms.queryMBeans(name2, null);
     55     }
     56     
     57     /**
     58      * 動態(tài)Mbean,需要實現(xiàn)DynamicMBean接口,并且任何需要,管理的方法、屬性,都需要在接口的方法中,
     59      * 自己來實現(xiàn),Mbeaninfo也需要自己設置,這樣編程的工作量大,但是有很大的可控性。
     60      * @throws Exception
     61      */
     62     @Test
     63     public void test2DynamicMBean() throws Exception{
     64         HelloWorldDynamic dynamic = new HelloWorldDynamic();
     65         
     66         MBeanServer ms = MBeanServerFactory.createMBeanServer();
     67         //創(chuàng)建一個ObjectName
     68         ObjectName name = new ObjectName("DynamicHello:type=dinamicMbean");
     69         
     70         //注冊動態(tài)MBean到MBeanServer服務上去
     71         ms.registerMBean(dynamic, name);
     72         
     73         //得到屬性值
     74         Object o = ms.getAttribute(name, "getInstance");
     75         String hello = (String)ms.getAttribute(name, "gh");
     76         MBeanOperationInfo operation = dynamic.getMBeanInfo().getOperations()[0];
     77         System.out.println(" attribute value of getInstance:"+o+"; attribute value of gh:"+hello);
     78         
     79         //執(zhí)行一個方法(操作)
     80         ms.invoke(name, operation.getName(), nullnull);
     81     }
     82     
     83     @Test
     84     public void test3RequiredModelMBean() throws Exception{
     85         HelloWorldModelMBean hello = new HelloWorldModelMBean();
     86         
     87         MBeanServer ms = MBeanServerFactory.createMBeanServer();
     88         RequiredModelMBean modelMbean = hello.createModelBean();
     89         ObjectName name = new ObjectName("RequiredMBeanHello:type=ModelMbean");
     90         //監(jiān)聽屬性變化事件
     91         modelMbean.addAttributeChangeNotificationListener(new NotificationListener() {
     92             @Override
     93             public void handleNotification(Notification notification, Object handback) {
     94                 System.out.println(" --Attribute已經(jīng)改變-- ");
     95             }
     96         }, null,null);
     97         ms.registerMBean(modelMbean, name);
     98         
     99         ms.invoke(name, "setHello", new Object[]{" aaa "},new String[]{ "java.lang.String"});
    100         String s = (String)ms.getAttribute(name, "hello");
    101         //出發(fā)Attribute改變事件
    102         ms.setAttribute(name, new Attribute("hello", "bbb"));
    103         String s2 = (String)ms.getAttribute(name, "hello");
    104         System.out.println(s);
    105         System.out.println(s2);
    106     }
    107 }
    108 
         
    • MBean注冊
    圖:一個MBean被注冊進MBeanServer的流程圖


    JmxMBeanServer在register一個MBean的時候,主要的步驟:
    1. 查看MBean是否符合命名規(guī)則
    2. 創(chuàng)建一個DynamicMBean,如果需要注冊的是標準MBean,那么通過內(nèi)省機制,得到標準的MBean各種元數(shù)據(jù),這些數(shù)據(jù)封裝組合到MBeanInfo中,接著創(chuàng)建StandardMBeanSupport(StandardMBeanSupport是DynamicMBean的子類) 。
    3. JMX中按照ObjectName加上一次創(chuàng)建好的DynamicMBean,存入到Repository,Repository存的格式有點相當于Map的(key,value)。

    • MBeanServer的管理MBean分析
    代碼:MBeanServer.getAttribute(ObjectName name, String attribute)執(zhí)行部分源碼
     1  JmxMBeanServer:
     2       public Object getAttribute(ObjectName name, String attribute)
     3           throws MBeanException, AttributeNotFoundException,
     4                  InstanceNotFoundException, ReflectionException {
     5             //mbsInterceptor類型為DefaultMBeanServerInterceptor,也實現(xiàn)了MBeanServer接口,
     6             //JmxMBeanServer實現(xiàn)的MBeanServer接口的方法,基本都是由mbs代理執(zhí)行的。
     7           return mbsInterceptor.getAttribute(cloneObjectName(name), attribute);
     8       }
     9   
    10 DefaultMBeanServerInterceptor:
    11      public Object getAttribute(ObjectName name, String attribute)
    12          throws MBeanException, AttributeNotFoundException,
    13                 InstanceNotFoundException, ReflectionException {       
    14 
    15          //通過ObjectName(key)從Repository中得到注冊過的MBean
    16          final DynamicMBean instance = getMBean(name);
    17 
    18           //得到Attribute的值
    19           return instance.getAttribute(attribute);
    20     }
    21 StandardMBeanSupport:
    22     public final Object gtAttribute(String attribute)
    23             throws AttributeNotFoundException,
    24                    MBeanException,
    25                    ReflectionException {
    26         return perInterface.getAttribute(resource, attribute, getCookie());
    27     }  
    28 PerInterface:
    29     Object getAttribute(Object resource, String attribute, Object cookie)
    30             throws AttributeNotFoundException,
    31                    MBeanException,
    32                    ReflectionException {
    33         //得到Attribute屬性的方法,也就是MBean接口中定義的getXXX()方法
    34         final M cm = getters.get(attribute);
    35         if (cm == null) {
    36             final String msg;
    37             if (setters.containsKey(attribute))
    38                 msg = "Write-only attribute: " + attribute;
    39             else
    40                 msg = "No such attribute: " + attribute;
    41             throw new AttributeNotFoundException(msg);
    42         }
    43         //在調(diào)用進去的話,就是通過反射調(diào)用cm方法,得到屬性的值
    44         return introspector.invokeM(cm, resource, (Object[]) null, cookie);
    45     }

    其他的比如setAttribute(...),和invoke(...)方法就是把上個getAttribute(...)替換相應方法名就可以了。
    參照上面流程圖和JDK中JMX的實現(xiàn),可以看出JMX在內(nèi)部實現(xiàn)中,對于標準MBean,也是轉(zhuǎn)換成DynamicMBean(StandardMBeanSupport是DynamicMBean的子類)。

    • 相關(guān)的類說明
    MBeanServerConnection、  MBeanServer、JmxMBeanServer,DefaultMBeanServerInterceptor:
    MBeanServerConnection提供一種連接到MBeanServer的途徑,可以使本地的或者遠程的。MBeanServer是作為一個本地的MBeanServerConnection,用于管理MBean的一個服務。主要提供創(chuàng)建、注冊、移除MBean,MBean屬性的獲得和設置,MBean的操作(invoke),消息機制的支持,MBean的查詢,MBean信息的展示。但是MBeanServer雖然目的是管理和對注冊進來的MBean進行操作,但是沒有方法是可以直接得到MBean實例的,只能通過MBeanServer對MBean進行操作。
    圖:MBeanServer結(jié)構(gòu)

    圖:MBeanServer屬性


    PerInterface:
    在JMX內(nèi)省一個MBean的時候,代表了MBean實現(xiàn)的MBean接口的行為。其中的屬性getters代表了MBean接口的getXXX方法,setters代表了MBean接口的setXXX方法,ops代表了MBean的其他方法。MBean接口中的getXXX()和setXXX()方法,在標準MBean中代表了一個屬性的讀和寫,而其他的方法名,則代表著一個操作。MBeanServer調(diào)用的方式是不一樣的,前者調(diào)用getAttbute(...)和setAttbute(...),而后者是調(diào)用invoke(...);
    圖:PerInterface結(jié)構(gòu)


    MBeanInfo、MBeanAttributeInfo、MBeanConstructorInfo、MBeanNotificationInfo、MBeanOperationInfo:
            這些類構(gòu)成了MBean的所有信息。JMX利用Introspection機制分析MBean的數(shù)據(jù),得到此MBean的元數(shù)據(jù)(i.e. 描述一個方法、屬性的名稱、類型、返回值等)。
    MBeanAttributeInfo用于存放屬性相關(guān)的元數(shù)據(jù),MBeanConstructorInfo用于存放跟構(gòu)造器相關(guān)的元數(shù)據(jù),MBeanOperationInfo用于存放操作相關(guān)的元數(shù)據(jù),MBeanNotificationInfo用于存放JMX消息(事件)相關(guān)的元數(shù)據(jù)。MBeanInfo就是存放所有的這些元數(shù)新,JMX管理系統(tǒng)如果想知道一個MBean能管理的屬性或者能進行什么用的操作,那么都可以從MBeanInfo中獲得信息。

    圖:MBeanInfo構(gòu)成

    NotificationBroadcasterSupport、NotificationListener、NotificationFilter、NotificationBroadcaster:
    這些類就是提供MBean的消息機制。給予一個MBean發(fā)送消息,過濾消息、監(jiān)聽消息,執(zhí)行消息等。一個MBean需要消息功能的話,就需要實現(xiàn)以后這些類。

    圖:消息機制的結(jié)構(gòu)

    Introspector、MBeanIntrospector:
    JMX用這兩個類進行內(nèi)省,即通過他們能分析MBean的所有屬性、方法,然后進行封裝、轉(zhuǎn)化、存儲等,轉(zhuǎn)化成我們需要的數(shù)據(jù)結(jié)構(gòu)

    MBeanRegistration :
    用于一個MBean在注冊前后,或者注銷前后,做一些邏輯操作
    圖:MBeanRegistration結(jié)構(gòu)圖  


    Dynamic、MBeanSupport、StandardMBeanSupport、MXBeanSupport:
    即使MBean是標準形式的,但是JMX實現(xiàn)中,還是會生成一個動態(tài)的MBean,即StandardMBeanSupport,來封裝標準MBean。
    圖:Dynamic、MBeanSupport、StandardMBeanSupport、MXBeanSupport關(guān)系圖(列出部分屬性、接口)

           
           總結(jié):標準MBean按照一定編程規(guī)則(i.e. getXXX(),setXXX()),把需要管理的標準MBean的屬性和操作,加入到接口的方法中,然后標準MBean實現(xiàn)這個接口,這樣當標準MBean注冊到MBeanServer中后,MBeanServer就可以管理此MBean了。標準MBean在于想要新增一個管理的屬性或操作,都要先在接口中先新增一個方法,然后實現(xiàn)。

    DynamicMBean
    JMX管理的MBean除了標準MBean外,還可以是DynamicMBean。只要我們實現(xiàn)此接口,就可以被JMX Server管理。
    例子:
     1 package test.jmx;
     2 
     3 import java.lang.reflect.Method;
     4 
     5 import javax.management.Attribute;
     6 import javax.management.AttributeList;
     7 import javax.management.AttributeNotFoundException;
     8 import javax.management.DynamicMBean;
     9 import javax.management.InvalidAttributeValueException;
    10 import javax.management.MBeanAttributeInfo;
    11 import javax.management.MBeanException;
    12 import javax.management.MBeanInfo;
    13 import javax.management.MBeanOperationInfo;
    14 import javax.management.ReflectionException;
    15 
    16 public class HelloWorldDynamic implements DynamicMBean {
    17     public String hello;
    18     
    19 
    20     public HelloWorldDynamic() {
    21         this.hello = "Hello World! I am a Dynamic MBean";
    22     }
    23 
    24     public HelloWorldDynamic(String hello) {
    25         this.hello = hello;
    26     }
    27 
    28     public String getHello() {
    29         return hello;
    30     }
    31 
    32     public Object getInstance() {
    33         return new Object();
    34     }
    35 
    36     public void setHello(String hello) {
    37         this.hello = hello;
    38     }
    39 
    40     @Override
    41     public Object getAttribute(String attribute)
    42             throws AttributeNotFoundException, MBeanException,
    43             ReflectionException {
    44         //設置getAttribute的執(zhí)行邏輯
    45         if("getInstance".equals(attribute)){
    46             return getInstance();
    47         }
    48         
    49         return null;
    50     }
    51 
    52     @Override
    53     public AttributeList getAttributes(String[] attributes) {
    54         // TODO Auto-generated method stub
    55         return null;
    56     }
    57 
    58     MBeanInfo info = null;
    59     @Override
    60     public MBeanInfo getMBeanInfo()  {
    61         try {
    62             Class cls = this.getClass();
    63             // 用反射獲得 "getHello" 屬性的讀方法
    64             //DynamicMBean中,
    65             Method readMethod = cls.getMethod("getHello", new Class[0]);
    66             MBeanAttributeInfo attribute = new MBeanAttributeInfo("gh",
    67                     " the first attribute ", readMethod, null);
    68             //執(zhí)行java類的method需要的一些元數(shù)據(jù),由MBeanOperationInfo提供
    69             MBeanOperationInfo operation = new MBeanOperationInfo(
    70                     " the first operation ", cls.getMethod("getInstance", null));
    71             info = new MBeanInfo(cls.getName(), " this is a dynamic MBean ",
    72                     new MBeanAttributeInfo[] { attribute }, null,
    73                     new MBeanOperationInfo[] { operation }, null);
    74         } catch (Exception e) {
    75             System.out.println(e);
    76         }
    77         return info;
    78     }
    79 
    80     @Override
    81     public Object invoke(String actionName, Object[] params, String[] signature)
    82             throws MBeanException, ReflectionException {
    83         System.out.println(" the HelloWorldDynamic's method invoke  ");
    84         return null;
    85     }
    86 
    87     @Override
    88     public void setAttribute(Attribute attribute)
    89             throws AttributeNotFoundException, InvalidAttributeValueException,
    90             MBeanException, ReflectionException {
    91         
    92     }
    93 
    94     @Override
    95     public AttributeList setAttributes(AttributeList attributes) {
    96         return null;
    97     }
    98 }
    99 

    測試此MBean請看JmxTest類中的test2DynamicMBean()。

           當實現(xiàn)一個DynamicMBean,我們需要寫的代碼量是非常多的,MBeanInfo的信息,需要自己編碼,而且對于MBeanServer操作MBean的方法,也得自己重載實現(xiàn)。在動態(tài)MBean中,MBeanInfo里面的信息,主要用來展示的,具體的對DynamicMBean的操作是自己實現(xiàn)的。DynamicMBean的優(yōu)點是對于邏輯控制是可以很靈活的。而不像標準MBean一樣,所有的操作或?qū)傩孕枰贛Bean接口中定義。在jdk中JMX實現(xiàn)DynamicMBean的流程是非常簡單的,Jmx server對于DynamicMBean的操作也是非常簡單的,相對于標準MBean,注冊的時候少了內(nèi)省的步驟;其他的操作跟標準MBean一樣,只是對于getAttribute(...),setAttribute(...),invoke(...)等一些的操作都是需要自己來實現(xiàn)的。

    ModelMBean
          然而,普通的動態(tài) Bean通常缺乏一些管理系統(tǒng)所需要的支持:比如持久化MBean的狀態(tài)、日志記錄、緩存等等。如果讓用戶去一一實現(xiàn)這些功能確實是件枯燥無聊的工作。為了減輕用戶的負擔,JMX提供商都會提供不同的 ModelBean實現(xiàn)。其中有一個接口是 Java 規(guī)范中規(guī)定所有廠商必須實現(xiàn)的:javax.management.modelmbean.RequiredModelBean。通過配置Descriptor信息,我們可以定制這個ModelBean,指定哪些 MBean狀態(tài)需要記入日志、如何記錄以及是否緩存某些屬性、緩存多久等等。對于Descriptor,在MBean中相當于附帶的一些信息,這些信息在MBean實現(xiàn)中可以作為一種策略,以此增強MBean的功能。動態(tài)MBean以及標準MBean的MBeanInfo都已經(jīng)包括了Descriptor,但是在邏輯實現(xiàn)中沒用到此對象。在ModelMBean中,Descriptor作用非常大,持久化、日志、緩存等的策略等相關(guān)信息都是在Descriptor中定義的。開發(fā)人員可以增加相關(guān)屬性到Descriptor中,來對應用功能進行擴展 
    這里,我們以 RequiredModelBean 為例討論 ModelBean。
    例子:
      1 package test.jmx;
      2 
      3 import java.lang.reflect.Constructor;
      4 
      5 import javax.management.Descriptor;
      6 import javax.management.InstanceNotFoundException;
      7 import javax.management.MBeanException;
      8 import javax.management.MBeanOperationInfo;
      9 import javax.management.MBeanParameterInfo;
     10 import javax.management.RuntimeOperationsException;
     11 import javax.management.modelmbean.DescriptorSupport;
     12 import javax.management.modelmbean.InvalidTargetObjectTypeException;
     13 import javax.management.modelmbean.ModelMBeanAttributeInfo;
     14 import javax.management.modelmbean.ModelMBeanConstructorInfo;
     15 import javax.management.modelmbean.ModelMBeanInfo;
     16 import javax.management.modelmbean.ModelMBeanInfoSupport;
     17 import javax.management.modelmbean.ModelMBeanOperationInfo;
     18 import javax.management.modelmbean.RequiredModelMBean;
     19 
     20 public class HelloWorldModelMBean extends RequiredModelMBean {
     21     
     22     public HelloWorldModelMBean() throws Exception{}
     23     
     24     public static RequiredModelMBean createModelBean()
     25             throws RuntimeOperationsException, MBeanException,
     26             InstanceNotFoundException, InvalidTargetObjectTypeException {
     27         // 模型MBean信息
     28         ModelMBeanInfo info = buildModelMBeanInfo();
     29         // 模型MBean
     30         RequiredModelMBean modelMBean = new RequiredModelMBean(info);
     31         //目前只支持ObjectReference,將來可能會支持ObjectReference", "Handle", "IOR", "EJBHandle",
     32          //         or "RMIReference,
     33         //RMIReference從名字上可以看出,如果支持的話,那么以后就可以支持遠程MBean引用
     34         modelMBean.setManagedResource(new HelloWorld(), "ObjectReference");
     35         return modelMBean;
     36     }
     37 
     38     protected static ModelMBeanInfo buildModelMBeanInfo() throws RuntimeOperationsException, MBeanException {  
     39         // --  
     40         // attributes  
     41         // ------------------------------------------------------------------  
     42         ModelMBeanAttributeInfo[] attributes = new ModelMBeanAttributeInfo[1];  
     43   
     44         // 設置屬性
     45         Descriptor nameDesc = new DescriptorSupport();  
     46         nameDesc.setField("name", "hello");
     47         nameDesc.setField("value", "----dfdf---");
     48         nameDesc.setField("displayName", "myname");  
     49         nameDesc.setField("setMethod", "setHello");  
     50         nameDesc.setField("getMethod", "getHello");  
     51         nameDesc.setField("descriptorType", "attribute"); 
     52         attributes[0] = new ModelMBeanAttributeInfo("hello", "java.lang.String",  
     53                 "name say hello to", truetruefalse, nameDesc);  
     54   
     55         // --  
     56         // operations  
     57         // -------------------------------------------------------------------  
     58         ModelMBeanOperationInfo[] operations = new ModelMBeanOperationInfo[2];  
     59         String className = HelloWorld.class.getName();  
     60   
     61         // getName method  
     62         Descriptor getDesc = new DescriptorSupport(new String[] {  
     63                 "name=getHello", "descriptorType=operation",  
     64                 "class=" + className, "role=operation" });  
     65         operations[0] = new ModelMBeanOperationInfo("getHello", "get hello  ",  
     66                 nullnull, MBeanOperationInfo.ACTION,  getDesc);  
     67        
     68         Descriptor setDesc = new DescriptorSupport(new String[] {  
     69                 "name=setHello", "descriptorType=operation", 
     70                 "class=" + className, "role=operation" });  
     71         operations[1] = new ModelMBeanOperationInfo("setHello", "set hello  ",  
     72                 new MBeanParameterInfo[]{new MBeanParameterInfo("a","java.lang.String"," a method's arg ")},
     73                 null, MBeanOperationInfo.ACTION,  setDesc);  
     74   
     75         // constructors  
     76         ModelMBeanConstructorInfo[] constructors = new ModelMBeanConstructorInfo[1];  
     77         Constructor<?>[] ctors = HelloWorld.class.getConstructors();  
     78   
     79   
     80         constructors[0] = new ModelMBeanConstructorInfo("default constructor",  
     81                 ctors[0], null);  
     82   
     83         // ModelMBeanInfo  
     84         ModelMBeanInfo mmbeanInfo = new ModelMBeanInfoSupport(className,  
     85                 "Simple implementation of model bean.", attributes, null,  
     86                 operations/*null*/nullnull);  
     87         
     88         //設置一個Descriptor策略,這樣RequiredModelMBean改變 Attribute值得時候會記錄日志
     89         //當然RequiredModelMBean還需要addAttributeChangeNotificationListener,注冊一個監(jiān)聽器
     90         Descriptor globalDescriptor = new DescriptorSupport(new String[]{
     91                 "name=HelloWorldModelMBean","displayName=globaldescriptor",
     92                 "descriptorType=mbean","log=T","logfile=hello.log"
     93         });
     94         mmbeanInfo.setMBeanDescriptor(globalDescriptor);
     95         
     96         return mmbeanInfo;  
     97     }  
     98 
     99 }
    100 

    使用ModelMBean中,有兩步很重要,第一步設置動態(tài)MBean元數(shù)據(jù):setModelMBeanInfo(...),MBeanServer會利用這些元數(shù)據(jù)管理MBean。第二步設置ModelMBean需要管理的對象:setManagerdResourece(...),第一步的元數(shù)據(jù)其實也就是被管理對象的元數(shù)據(jù)。這二步都是可以在運行時候動態(tài)的配置的,對于ModelMBeanInfo和Resource等相關(guān)信息可以在xml文件中進行配置。所以對于ModelMBean的實現(xiàn),可以很好的利用xml等工具。

    測試此MBean請看JmxTest類中的test3RequiredModelMBean()方法。  

    代碼:RequiredModelMBean.setAttribute(...)的執(zhí)行分析
     1 JmxMBeanServer:
     2     public void setAttribute(ObjectName name, Attribute attribute)
     3         throws InstanceNotFoundException, AttributeNotFoundException,
     4                InvalidAttributeValueException, MBeanException,
     5                ReflectionException  {
     6 
     7         mbsInterceptor.setAttribute(cloneObjectName(name),
     8                                     cloneAttribute(attribute));
     9     }
    10 
    11 DefaultMBeanServerInterceptor:
    12     public void setAttribute(ObjectName name, Attribute attribute)
    13         throws InstanceNotFoundException, AttributeNotFoundException,
    14                InvalidAttributeValueException, MBeanException,
    15                ReflectionException  {
    16 .
    17         //得到動態(tài)MBean
    18         DynamicMBean instance = getMBean(name);
    19         instance.setAttribute(attribute);
    20 .
    21     }
    22 
    23 RequiredModelMBean:
    24     public void setAttribute(Attribute attribute)
    25         throws AttributeNotFoundException, InvalidAttributeValueException,
    26                MBeanException, ReflectionException 
    27 .
    28        //modelMBeanInfo就是最開始創(chuàng)建的信息,得到一個AttributeInfo
    29         ModelMBeanAttributeInfo attrInfo =
    30             modelMBeanInfo.getAttribute(attrName);
    31 .
    32         Descriptor mmbDesc = modelMBeanInfo.getMBeanDescriptor();
    33         Descriptor attrDescr = attrInfo.getDescriptor();
    34 .
    35             //得到set方法名
    36             String attrSetMethod = (String)
    37                 (attrDescr.getFieldValue("setMethod"));
    38             //得到get方法名
    39             String attrGetMethod = (String)
    40                 (attrDescr.getFieldValue("getMethod"));
    41 .
    42             //更具必要參數(shù),執(zhí)行set方法。改變被管理資源的值
    43                 invoke(attrSetMethod,
    44                        (new Object[] {attrValue}),
    45                        (new String[] {attrType}) );
    46 .
    47             //發(fā)出Attribute改變的事件
    48             sendAttributeChangeNotification(oldAttr,attribute);
    49 
    50     }
    51     public void sendAttributeChangeNotification(AttributeChangeNotification
    52                                                 ntfyObj)
    53         throws MBeanException, RuntimeOperationsException {
    54 .
    55         // log notification if specified in descriptor
    56         Descriptor ntfyDesc =
    57             modelMBeanInfo.getDescriptor(ntfyObj.getType(),"notification");
    58         //這個就是在例子中設置的globalDescriptor
    59         Descriptor mmbDesc = modelMBeanInfo.getMBeanDescriptor();
    60 .
    61  if (mmbDesc != null) {
    62             //這些值都是我們設置在globalDescriptor的策略,也就是具體                              //需要JMX的實現(xiàn)這需要各自實現(xiàn)的策略
    63             logging = (String) mmbDesc.getFieldValue("log");
    64             if ((logging != null) &&
    65                 ( logging.equalsIgnoreCase("t") ||
    66                   logging.equalsIgnoreCase("true") )) {
    67                 logfile = (String) mmbDesc.getFieldValue("logfile");
    68 
    69                 if (logfile != null) {
    70                     try {
    71                        //把相關(guān)信息寫入日志
    72                         writeToLog(logfile,"LogMsg: " +
    73                            ((new Date(ntfyObj.getTimeStamp())).toString())+
    74                            " " + ntfyObj.getType() + " " +
    75                            ntfyObj.getMessage() +
    76                            " Name = " + ntfyObj.getAttributeName() +
    77                            " Old value = " + oldv +
    78                            " New value = " + newv);
    79                     }
    80 
    81     }
    82 

    在ModelMBean中一些重要的類:
    ModelMBean:
    實現(xiàn)了DynamicMBean,說明了ModelMBean也是動態(tài)MBean的一類,PersistentMBean持久化功能接口,還實現(xiàn)了消息機制。
    圖:ModelMBean的結(jié)構(gòu)圖


    ModelMBeanInfo、ModelMBeanAttributeInfo、ModelMBeanConstructorInfo、ModelMBeanNotificationInfo、ModelMBeanOperationInfo:
    這些類跟DynamicMBean里面介紹的類很相似,這里的ModelXXX都是XXX的子類。而且構(gòu)成也跟他們的父類是一樣的,子類只是擴展了一些信息。

    RequiredModelMBean:
    RequiredModelMBean實現(xiàn)了ModelMBean其實實現(xiàn)了DynamicMBean,其實它也是一個動態(tài)的MBean,規(guī)范中說明對于使用ModelMBean,第三方供應商都必須實現(xiàn)RequiredMoelMBean。 

    參考:
    http://www.ibm.com/developerworks/cn/java/j-lo-jse63/index.html(Java SE 6 新特性: JMX 與系統(tǒng)管理)

    posted on 2012-09-24 08:33 heavensay 閱讀(6985) 評論(0)  編輯  收藏 所屬分類: JMX


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導航:
     
    主站蜘蛛池模板: 亚洲国产成人久久笫一页| 亚洲日本在线免费观看| 黄页视频在线观看免费| 亚洲av无码专区在线观看亚| 亚洲国产精品美女久久久久| 亚洲AV无码专区在线电影成人 | 无码中文字幕av免费放| 99在线精品视频观看免费| 青草草色A免费观看在线| 免费看韩国黄a片在线观看| 精品久久久久久久久免费影院| 国产精品免费网站| 成年美女黄网站18禁免费| 国产精品免费一级在线观看| 无码专区一va亚洲v专区在线 | 亚洲国产精品成人一区| 久久影视国产亚洲| 亚洲国产精品一区二区第一页| 亚洲第一福利网站| 亚洲成A∨人片在线观看无码| 亚洲一区二区三区免费观看| 亚洲国产精品精华液| 伊人久久国产免费观看视频| 三级网站在线免费观看| 99re视频精品全部免费| 一二三四在线播放免费观看中文版视频 | 在线观看免费人成视频色9| 青草草在线视频永久免费| 亚洲国产一成久久精品国产成人综合 | 久久久久国色AV免费观看性色 | 久久久久国色av免费看| 一个人免费观看视频www| 无码欧精品亚洲日韩一区夜夜嗨| 亚洲精品一品区二品区三品区| 亚洲视频在线不卡| 久久精品国产亚洲av天美18| 最近国语视频在线观看免费播放| 亚洲黄色片免费看| 免费一级毛片女人图片| 亚洲高清在线观看| 噜噜综合亚洲AV中文无码|