动态MBean:DynamicMBean

来源:互联网 发布:工作计划软件 编辑:程序博客网 时间:2024/06/15 16:16
一、前言
 
  动态MBean是在运行期才定义它的属性和方法,也就是说它有什么属性和方法是可以动态改变的。动态MBean主要利用一些辅助类(构造函数类MBeanConstructorInfo、属性类MBeanAttributeInfo、方法类MBeanOperationInfo)来完成这个功能,所有的动态MBean必须实现DynamicMBean接口。DynamicMBean写好后,使用方法和第一篇文章中普通的MBean一样。
 
  给出一个动态MBean的实例,这个实例最初动态构了一个Name属性及一个print方法,当我们执行它的print方法之后,又给此MBean新增了一个print1方法。实例的代码如下:
二、实例

1、HelloDynamic类

import java.lang.reflect.Constructor;import java.util.Iterator;import javax.management.Attribute;import javax.management.AttributeList;import javax.management.DynamicMBean;import javax.management.MBeanAttributeInfo;import javax.management.MBeanConstructorInfo;import javax.management.MBeanException;import javax.management.MBeanInfo;import javax.management.MBeanNotificationInfo;import javax.management.MBeanOperationInfo;import javax.management.MBeanParameterInfo;import javax.management.ReflectionException;/** * @author Sunny Peng * @author change by Chen.Gang, add a feature for dynamic add operation * @version 1.0 */public class HelloDynamic implements DynamicMBean {    //这是我们的属性名称    private String name;    private MBeanInfo mBeanInfo = null;    private String className;    private String description;    private MBeanAttributeInfo[] attributes;    private MBeanConstructorInfo[] constructors;    private MBeanOperationInfo[] operations;    MBeanNotificationInfo[] mBeanNotificationInfoArray;    public HelloDynamic() {        init();        buildDynamicMBean();    }    private void init() {        className = this.getClass().getName();        description = "Simple implementation of a dynamic MBean.";        attributes = new MBeanAttributeInfo[1];        constructors = new MBeanConstructorInfo[1];        operations = new MBeanOperationInfo[1];        mBeanNotificationInfoArray = new MBeanNotificationInfo[0];    }    private void buildDynamicMBean() {        //设定构造函数        Constructor[] thisconstructors = this.getClass().getConstructors();        constructors[0] = new MBeanConstructorInfo("HelloDynamic(): Constructs a HelloDynamic object", thisconstructors[0]);        //设定一个属性        attributes[0] = new MBeanAttributeInfo("Name", "java.lang.String", "Name: name string.", true, true, false);        //operate method 我们的操作方法是print        MBeanParameterInfo[] params = null;//无参数        operations[0] = new MBeanOperationInfo("print", "print(): print the name", params, "void", MBeanOperationInfo.INFO);        mBeanInfo = new MBeanInfo(className, description, attributes, constructors, operations, mBeanNotificationInfoArray);    }    //动态增加一个print1方法    private void dynamicAddOperation() {        init();        operations = new MBeanOperationInfo[2];//设定数组为两个        buildDynamicMBean();        operations[1] = new MBeanOperationInfo("print1", "print1(): print the name", null, "void", MBeanOperationInfo.INFO);        mBeanInfo = new MBeanInfo(className, description, attributes, constructors, operations, mBeanNotificationInfoArray);    }    public Object getAttribute(String attribute_name) {        if (attribute_name != null)            return null;        if (attribute_name.equals("Name"))            return name;        return null;    }    public void setAttribute(Attribute attribute) {        if (attribute == null)            return;        String Name = attribute.getName();        Object value = attribute.getValue();        try {            if (Name.equals("Name")) {                // if null value, try and see if the setter returns any exception                if (value == null) {                    name = null;                    // if non null value, make sure it is assignable to the attribute                } else if ((Class.forName("java.lang.String")).isAssignableFrom(value.getClass())) {                    name = (String) value;                }            }        } catch (Exception e) {            e.printStackTrace();        }    }    public AttributeList getAttributes(String[] attributeNames) {        if (attributeNames == null)            return null;        AttributeList resultList = new AttributeList();        // if attributeNames is empty, return an empty result list        if (attributeNames.length == 0)            return resultList;        for (int i = 0; i < attributeNames.length; i++) {            try {                Object value = getAttribute(attributeNames[i]);                resultList.add(new Attribute(attributeNames[i], value));            } catch (Exception e) {                e.printStackTrace();            }        }        return resultList;    }    public AttributeList setAttributes(AttributeList attributes) {        if (attributes == null)            return null;        AttributeList resultList = new AttributeList();        // if attributeNames is empty, nothing more to do        if (attributes.isEmpty())            return resultList;        // for each attribute, try to set it and add to the result list if successfull        for (Iterator i = attributes.iterator(); i.hasNext();) {            Attribute attr = (Attribute) i.next();            try {                setAttribute(attr);                String name = attr.getName();                Object value = getAttribute(name);                resultList.add(new Attribute(name, value));            } catch (Exception e) {                e.printStackTrace();            }        }        return resultList;    }    public Object invoke(String operationName, Object params[], String signature[]) throws MBeanException, ReflectionException {        // Check for a recognized operation name and call the corresponding operation        if (operationName.equals("print")) {            //具体实现我们的操作方法print             System.out.println("Hello, " + name + ", this is HellDynamic!");            dynamicAddOperation();            return null;        } else if (operationName.equals("print1")) {            System.out.println("这是动态增加的一方法print1");            return null;        } else {            // unrecognized operation name:            throw new ReflectionException(new NoSuchMethodException(operationName), "Cannot find the operation " + operationName + " in " + className);        }    }    public MBeanInfo getMBeanInfo() {        return mBeanInfo;    }}

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

3、运行
 
  先运行HelloAgent。再打开浏览器,输入网址:http://localhost:8082/。单击进入“name=HelloDynamic ”项,执行print方法后再回到上一页面你会发现又多了一个print1方法。
 
4、总结
  动态MBean的代码稍显复杂,但对于一些特殊需求的情况,它将显示出强大威力。而且它还是模型MBeans(Model MBeans)的基础。不过在一般的项目中,动态MBean还是用得比较少,所谓利器深藏之而不用,非常时方现光芒。



转载地址:http://www.blogjava.net/chengang/archive/2006/03/07/34084.html

原创粉丝点击