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

一、前言
 
  动态MBean是在运行期才定义它的属性和方法,也就是说它有什么属性和方法是可以动态改变的。动态MBean主要利用一些辅助类(构造函数类MBeanConstructorInfo、属性类MBeanAttributeInfo、方法类MBeanOperationInfo)来完成这个功能,所有的动态MBean必须实现DynamicMBean接口。DynamicMBean写好后,使用方法和第一篇文章中普通的MBean一样。
 
  给出一个动态MBean的实例,这个实例最初动态构了一个Name属性及一个print方法,当我们执行它的print方法之后,又给此MBean新增了一个print1方法。实例的代码如下:
二、实例
1、HelloDynamic类
java 代码
  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而已。为了实例完整,也一并帖出来吧。
java 代码
  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.     }   
  17.   
3、运行
 
  先运行HelloAgent。再打开浏览器,输入网址: http://localhost:8082/。单击进入“ name=HelloDynamic ”项,执行print方法后再回到上一页面你会发现又多了一个print1方法。
 
4、总结
  动态MBean的代码稍显复杂,但对于一些特殊需求的情况,它将显示出强大威力。而且它还是模型MBeans(Model MBeans)的基础。不过在一般的项目中,动态MBean还是用得比较少,所谓利器深藏之而不用,非常时方现光芒。

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