[JMX一步步来] 4、动态MBean:DynamicMBean

一、前言
   
动态MBean是在运行期才定义它的属性和方法,也就是说它有什么属性和方法是可以动态改变的。动态MBean主要利用一 些辅助类(构造函数类MBeanConstructorInfo、属性类MBeanAttributeInfo、方法类 MBeanOperationInfo)来完成这个功能,所有的动态MBean必须实现DynamicMBean接口。DynamicMBean写好后, 使用方法和第一篇文章中普通的MBean一样。

   
给出一个动态MBean的实例,这个实例最初动态构了一个Name属性及一个print方法,当我们执行它的print方法之后,又给此MBean新增了一个print1方法。实例的代码如下:

二、实例
1、HelloDynamic类
  1. import java.lang.reflect.Constructor;  
  2. import java.util.Iterator;  
  3. import javax.management.Attribute;  
  4. import javax.management.AttributeList;  
  5. import javax.management.DynamicMBean;  
  6. import javax.management.MBeanAttributeInfo;  
  7. import javax.management.MBeanConstructorInfo;  
  8. import javax.management.MBeanException;  
  9. import javax.management.MBeanInfo;  
  10. import javax.management.MBeanNotificationInfo;  
  11. import javax.management.MBeanOperationInfo;  
  12. import javax.management.MBeanParameterInfo;  
  13. import javax.management.ReflectionException;  
  14.   
  15. /** 
  16.  * @author Sunny Peng 
  17.  * @author change by Chen.Gang, add a feature for dynamic add operation 
  18.  * @version 1.0 
  19.  */  
  20. public class HelloDynamic implements DynamicMBean {  
  21.     //这是我们的属性名称  
  22.     private String name;  
  23.     private MBeanInfo mBeanInfo = null;  
  24.     private String className;  
  25.     private String description;  
  26.     private MBeanAttributeInfo[] attributes;  
  27.     private MBeanConstructorInfo[] constructors;  
  28.     private MBeanOperationInfo[] operations;  
  29.     MBeanNotificationInfo[] mBeanNotificationInfoArray;  
  30.   
  31.     public HelloDynamic() {  
  32.         init();  
  33.         buildDynamicMBean();  
  34.     }  
  35.   
  36.     private void init() {  
  37.         className = this.getClass().getName();  
  38.         description = "Simple implementation of a dynamic MBean.";  
  39.         attributes = new MBeanAttributeInfo[1];  
  40.         constructors = new MBeanConstructorInfo[1];  
  41.         operations = new MBeanOperationInfo[1];  
  42.         mBeanNotificationInfoArray = new MBeanNotificationInfo[0];  
  43.     }  
  44.   
  45.     private void buildDynamicMBean() {  
  46.         //设定构造函数  
  47.         Constructor[] thisconstructors = this.getClass().getConstructors();  
  48.         constructors[0] = new MBeanConstructorInfo("HelloDynamic(): Constructs a HelloDynamic object", thisconstructors[0]);  
  49.         //设定一个属性  
  50.         attributes[0] = new MBeanAttributeInfo("Name""java.lang.String""Name: name string."truetruefalse);  
  51.         //operate method 我们的操作方法是print  
  52.         MBeanParameterInfo[] params = null;//无参数  
  53.         operations[0] = new MBeanOperationInfo("print""print(): print the name", params, "void", MBeanOperationInfo.INFO);  
  54.         mBeanInfo = new MBeanInfo(className, description, attributes, constructors, operations, mBeanNotificationInfoArray);  
  55.     }  
  56.   
  57.     //动态增加一个print1方法  
  58.     private void dynamicAddOperation() {  
  59.         init();  
  60.         operations = new MBeanOperationInfo[2];//设定数组为两个  
  61.         buildDynamicMBean();  
  62.         operations[1] = new MBeanOperationInfo("print1""print1(): print the name"null"void", MBeanOperationInfo.INFO);  
  63.         mBeanInfo = new MBeanInfo(className, description, attributes, constructors, operations, mBeanNotificationInfoArray);  
  64.     }  
  65.   
  66.     public Object getAttribute(String attribute_name) {  
  67.         if (attribute_name != null)  
  68.             return null;  
  69.         if (attribute_name.equals("Name"))  
  70.             return name;  
  71.         return null;  
  72.     }  
  73.   
  74.     public void setAttribute(Attribute attribute) {  
  75.         if (attribute == null)  
  76.             return;  
  77.         String Name = attribute.getName();  
  78.         Object value = attribute.getValue();  
  79.         try {  
  80.             if (Name.equals("Name")) {  
  81.                 // if null value, try and see if the setter returns any exception  
  82.                 if (value == null) {  
  83.                     name = null;  
  84.                     // if non null value, make sure it is assignable to the attribute  
  85.                 } else if ((Class.forName("java.lang.String")).isAssignableFrom(value.getClass())) {  
  86.                     name = (String) value;  
  87.                 }  
  88.             }  
  89.         } catch (Exception e) {  
  90.             e.printStackTrace();  
  91.         }  
  92.     }  
  93.   
  94.     public AttributeList getAttributes(String[] attributeNames) {  
  95.         if (attributeNames == null)  
  96.             return null;  
  97.         AttributeList resultList = new AttributeList();  
  98.         // if attributeNames is empty, return an empty result list  
  99.         if (attributeNames.length == 0)  
  100.             return resultList;  
  101.         for (int i = 0; i < attributeNames.length; i++) {  
  102.             try {  
  103.                 Object value = getAttribute(attributeNames[i]);  
  104.                 resultList.add(new Attribute(attributeNames[i], value));  
  105.             } catch (Exception e) {  
  106.                 e.printStackTrace();  
  107.             }  
  108.         }  
  109.         return resultList;  
  110.     }  
  111.   
  112.     public AttributeList setAttributes(AttributeList attributes) {  
  113.         if (attributes == null)  
  114.             return null;  
  115.         AttributeList resultList = new AttributeList();  
  116.         // if attributeNames is empty, nothing more to do  
  117.         if (attributes.isEmpty())  
  118.             return resultList;  
  119.         // for each attribute, try to set it and add to the result list if successfull  
  120.         for (Iterator i = attributes.iterator(); i.hasNext();) {  
  121.             Attribute attr = (Attribute) i.next();  
  122.             try {  
  123.                 setAttribute(attr);  
  124.                 String name = attr.getName();  
  125.                 Object value = getAttribute(name);  
  126.                 resultList.add(new Attribute(name, value));  
  127.             } catch (Exception e) {  
  128.                 e.printStackTrace();  
  129.             }  
  130.         }  
  131.         return resultList;  
  132.     }  
  133.   
  134.     public Object invoke(String operationName, Object params[], String signature[]) throws MBeanException, ReflectionException {  
  135.         // Check for a recognized operation name and call the corresponding operation  
  136.         if (operationName.equals("print")) {  
  137.             //具体实现我们的操作方法print  
  138.             System.out.println("Hello, " + name + ", this is HellDynamic!");  
  139.             dynamicAddOperation();  
  140.             return null;  
  141.         } else if (operationName.equals("print1")) {  
  142.             System.out.println("这是动态增加的一方法print1");  
  143.             return null;  
  144.         } else {  
  145.             // unrecognized operation name:  
  146.             throw new ReflectionException(new NoSuchMethodException(operationName), "Cannot find the operation " + operationName + " in " + className);  
  147.         }  
  148.   
  149.     }  
  150.   
  151.     public MBeanInfo getMBeanInfo() {  
  152.         return mBeanInfo;  
  153.     }  
  154. }  
说明:
   
* 实现于接口DynamicMBean
   
* 借助于各种辅助类完成一个类的构造。构造函数类MBeanConstructorInfo、属性类MBeanAttributeInfo、方法类MBeanOperationInfo
   
* 这里所有public方法是实现于DynamicMBean的。主要提供:setAttribute设置属性、 getAttribute取得属性、setAttributes设置一组属性、getAttributes取得一组属性、invoke方法调用、 getMBeanInfo MBeanServer由这个方法得到关键的MBean类的构造信息。

2、HelloAgent类
   前面说了HelloDynamic和普通MBean的使用方法是一样的,因此HelloAgent和第一篇的HelloAgent基本一样,就是把Hello改成HelloDynamic而已。为了实例完整,也一并帖出来吧。
  1. import javax.management.MBeanServerFactory;  
  2. import javax.management.ObjectName;  
  3. import com.sun.jdmk.comm.HtmlAdaptorServer;  
  4. public class HelloAgent {  
  5.     public static void main(String[] args) throws Exception {  
  6.         MBeanServer server = MBeanServerFactory.createMBeanServer();  
  7.         ObjectName helloName = new ObjectName("chengang:name=HelloDynamic");  
  8.         HelloDynamic hello = new HelloDynamic();  
  9.         server.registerMBean(hello, helloName);  
  10.         ObjectName adapterName = new ObjectName("HelloAgent:name=htmladapter,port=8082");  
  11.         HtmlAdaptorServer adapter = new HtmlAdaptorServer();  
  12.         server.registerMBean(adapter, adapterName);  
  13.         adapter.start();  
  14.         System.out.println("start.....");  
  15.     }  
  16. }  

3、运行
  
先运行HelloAgent。再打开浏览器,输入网址:http://localhost:8082/。单击进入“name=HelloDynamic ”项,执行print方法后再回到上一页面你会发现又多了一个print1方法。

4、总结
  
动态MBean的代码稍显复杂,但对于一些特殊需求的情况,它将显示出强大威力。而且它还是模型MBeans(Model MBeans)的基础。不过在一般的项目中,动态MBean还是用得比较少,所谓利器深藏之而不用,非常时方现光芒。


你可能感兴趣的:(浏览器,sun)