[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.", true, true, false); 
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)