清单 10. 实现 DynamicMBean 接口
2 import javax.management.MBeanInfo;
3 import javax.management.DynamicMBean;
4 import javax.management.Attribute;
5 import javax.management.AttributeList;
6 import javax.management.MBeanInfo;
7 import javax.management.MBeanAttributeInfo;
8 import javax.management.MBeanConstructorInfo;
9 import javax.management.MBeanOperationInfo;
10 public class ClickMeterDyn extends ClickMeterInstrm implements DynamicMBean {
11 public ClickMeterDyn() {
12 }
13 public static void main(String[] args) {
14 setLandF();
15 ClickMeterDyn cms = new ClickMeterDyn();
16 // can use standard MBean agent - same logic
17 BaseStdAgent myAgent = new BaseStdAgent();
18 myAgent.startAgent((Object) cms);
19 }
20 // implements the dynamic MBean interface
21 public Object getAttribute(String inAttrName) {
22 if (inAttrName.equals( " PanelValue " ))
23 return ((Object) getPanelValue());
24 else
25 return null ;
26 }
27 public void setAttribute(Attribute attribute) {
28 if (attribute.getName().equals( " PanelValue " ))
29 setPanelValue((Integer) attribute.getValue());
30 }
31 public AttributeList getAttributes(String[] attributeNames) {
32 AttributeList resultList = new AttributeList();
33 for ( int i = 0 ; i < attributenames.length ; i ++ ){
34 try {
35 resultlist.add( new attribute(attributenames[i],
36 (object) getattribute( (string) attributenames[i])
37 ));
38 } catch (exception e) {
39 e.printstacktrace();
40 }
41 }
42 return (resultlist);
43 }
44 public attributelist setattributes(attributelist attributes) {
45 attributelist resultlist = " new " attributelist();
46 for ( int i = " 0; " i < attributes.size(); i ++ ) {
47 attribute attr = " (Attribute) " attributes.get(i);
48 try {
49 setattribute(attr);
50 string name = " attr.getName(); "
51 resultlist.add( new attribute(name,
52 (object) getattribute(name)));
53 } catch (exception e) {
54 e.printstacktrace();
55 } }
56 return (resultlist);
57 }
58 public object invoke(string opname, object params[], string signature[]) {
59 if (opname.equals( " incPanelValue " )){
60 incPanelValue();
61 } else {
62 if (opname.equals( " decPanelValue " )) {
63 decPanelValue();
64 }
65 }
66 return null ;
67 }
68 public mbeaninfo getmbeaninfo() {
69 mbeanattributeinfo [] mbai = " new " mbeanattributeinfo[ 1 ];
70 mbai[ 0 ] = " new " mbeanattributeinfo( " panelvalue " ,
71 " java.lang.integer " ,
72 " the panel value " ,
73 true ,
74 true ,
75 false );
76 mbeanconstructorinfo [] mbci = " new " mbeanconstructorinfo[ 1 ];
77 mbci[ 0 ] = " new " mbeanconstructorinfo( " clickmeterdyn " ,
78 " dynamic mbean click meter " , null );
79 mbeanoperationinfo [] mboi = " new " mbeanoperationinfo[ 2 ];
80 mboi[ 0 ] = " new " mbeanoperationinfo( " incpanelvalue " ,
81 " increment the meter value " , null , " void " , mbeanoperationinfo.action);
82 mboi[ 1 ] = " new " mbeanoperationinfo( " decpanelvalue " ,
83 " decrement the meter value " , null , " void " , mbeanoperationinfo.action);
84 return new mbeaninfo( " dwjmxservice.basic.clickmeterdyn " ,
85 " mbean:click meter " ,
86 mbai,
87 mbci,
88 mboi,
89 null );
90 }
91 }
92
这里要注意的第一件事是, ClickMeterDyn 按要求的那样直接实现了 DynamicMBean 接口。我们还可以看到动态 MBean 通过对 getMBeanInfo() 方法的调用获得元数据信息。该方法的代码和我们在模型 MBean 例子中看到的很类似,但不完全一样。主要的区别是我们不必将 PanelValue 属性的 getter 方法和 setter 方法重新定义为公开的操作的一部分。
针对属性的 getter/setter 方法,将入站属性的名称与我们唯一的属性 PanelValue 进行比较,并相应地从 ClickPanelModel 读写值。 invoke() 方法通过比较入站操作的名称和我们所支持的两个操作( incPanelValue 或 decPanelValue )来进行处理。由于这些操作不使用入站参数且不返回值,因此进行匹配时我们只需调用 ClickMeterInstrm 类中相应的 incPanelValue() 方法或 decPanelValue() 方法。
测试动态 MBean
请注意,在清单 10 中 ClickMeterDyn 实际上使用了 BaseStdAgent 作为其 JMX 代理。这是因为使用动态 MBean 或标准 MBean 时从代理的角度来看,没有操作上的区别。同样,JMX 体系结构给予它最大的灵活性和可扩展性。
使用 compile.bat 文件编译动态 MBean 示例,或者执行下列命令行:
2 < jmx install dir > \lib\jmxri.jar;
3 < jmx install dir > \lib\jmxtools.jar
4 - d classes src\dwjmxservice\basic\ * .java
5
使用 rundyn.bat 文件运行动态 MBean 示例,或者在代码子目录中执行下列命令行:
2 < jmx install dir > \lib\jmxri.jar;
3 < jmx install dir > \lib\jmxtools.jar;
4 classes dwjmxservice.basic.ClickMeterDyn
5
当您测试动态 MBean 时,请注意它是如何完全像标准 MBean 示例运行的。
结束语
当您将工具添加到现有的设备或软件服务中时,您通常可选择使用标准 MBean 或动态 MBean(包括模型 MBean)。标准 MBean 适合用于快速工具,但是不适合用于更改。动态 MBean 对于公开的属性、操作和事件的更改是有“弹性”的;但是, 对它们进行编程需要做更多的工作。使用模型 MBean 则取两家之长,支持自适应更改而无需大量编码和测试。