不用 RequiredModelMBean 来实现 DynamicMBean
将动态 MBean 工具添加到 ClickMeter 类是有关实现 javax.management.DynamicMBean 接口的所有方法的问题。我们创建名为 ClickMeterDyn 的 ClickMeterInstrm 子类来做到这一点。清单 10 显示了 ClickMeterDyn 的代码:
清单 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 则取两家之长,支持自适应更改而无需大量编码和测试。