阅读更多
在上一节是用apache的commons-modeler来开发的一个model,只不过commons-modeler帮助我们实现了很多的代码,而 我们只需要写描述XML文件就行了。这一节,来一个实打实的Model Bean,不借助任何第三方工具包。例子还是沿用Hello这个类,以便于和以前的实现相比较。
一、Model MBean实例
1、Hello.java还是和以前的一样。这里它没有再加上一个MBean接口了,只是一个很普通的类
1.public class Hello{
2. private String name;
3. public String getName() {
4. return name;
5. }
6. public void setName(String name) {
7. this.name = name;
8. }
9. public void printHello() {
10. System.out.println("Hello World, " + name);
11. }
12. public void printHello(String whoName) {
13. System.out.println("Hello , " + whoName);
14. }
15.}
2、接下来是HelloAgent的写法,和以前就差一句:把“new Hello()”这一句删除了,加上了ModelMbeanUtils.createModlerMbean();
1.import javax.management.MBeanServer;
2.import javax.management.MBeanServerFactory;
3.import javax.management.ObjectName;
4.import javax.management.modelmbean.RequiredModelMBean;
5.
6.import com.sun.jdmk.comm.HtmlAdaptorServer;
7.
8.public class HelloAgent {
9. public static void main(String[] args) throws Exception {
10. MBeanServer server = MBeanServerFactory.createMBeanServer();
11. ObjectName helloName = new ObjectName("chengang:name=HelloWorld");
12. //Hello hello = new Hello();
13. RequiredModelMBean hello = ModelMBeanUtils.createModlerMBean();
14. server.registerMBean(hello, helloName);
15. ObjectName adapterName = new ObjectName("HelloAgent:name=htmladapter,port=8082");
16. HtmlAdaptorServer adapter = new HtmlAdaptorServer();
17. server.registerMBean(adapter, adapterName);
18. adapter.start();
19. System.out.println("start.....");
20. }
21.}
3、ModelMbeanUtils这个类是要我们自己来实现的,也是写model Bean最麻烦的地方,它主要是返回一个RequiredModelMBean类,此类主要包括了一个ModelMBeanInfo类的信息。在 ModelMBeanInfo中定义了所有对需要管理的属性和方法的描述。具体代码如下:
1.import javax.management.MBeanParameterInfo;
2.import javax.management.modelmbean.ModelMBeanAttributeInfo;
3.import javax.management.modelmbean.ModelMBeanInfo;
4.import javax.management.modelmbean.ModelMBeanInfoSupport;
5.import javax.management.modelmbean.ModelMBeanOperationInfo;
6.import javax.management.modelmbean.RequiredModelMBean;
7.public class ModelMBeanUtils {
8. private static final boolean READABLE = true;
9. private static final boolean WRITABLE = true;
10. private static final boolean BOOLEAN = true;
11. private static final String STRING_CLASS = "java.lang.String";
12. public static RequiredModelMBean createModlerMBean() {
13. RequiredModelMBean model = null;
14. try {
15. model = new RequiredModelMBean();
16. model.setManagedResource(new Hello(), "objectReference");
17. ModelMBeanInfo info = createModelMBeanInfo();
18. model.setModelMBeanInfo(info);
19. } catch (Exception e) {
20. e.printStackTrace();
21. }
22. return model;
23. }
24. private static ModelMBeanInfo createModelMBeanInfo() {
25. //////////////////////////////////////////////////////////////////
26. // 属性 //
27. //////////////////////////////////////////////////////////////////
28. // 构造name属性信息
29. ModelMBeanAttributeInfo nameAttrInfo = new ModelMBeanAttributeInfo(//
30. "Name", // 属性名
31. STRING_CLASS, //属性类型
32. "people name", // 描述文字
33. READABLE, WRITABLE, !BOOLEAN, // 读写
34. null // 属性描述子
35. );
36. //////////////////////////////////////////////////////////////////
37. // 方法 //
38. //////////////////////////////////////////////////////////////////
39. //构造 printHello()操作的信息
40. ModelMBeanOperationInfo print1Info = new ModelMBeanOperationInfo(//
41. "printHello", //
42. null, //
43. null, //
44. "void", //
45. MBeanOperationInfo.INFO, //
46. null //
47. );
48. // 构造printHello(String whoName)操作信息
49. ModelMBeanOperationInfo print2Info;
50. MBeanParameterInfo[] param2 = new MBeanParameterInfo[1];
51. param2[0] = new MBeanParameterInfo("whoName", STRING_CLASS, "say hello to who");
52. print2Info = new ModelMBeanOperationInfo(//
53. "printHello", //
54. null,//
55. param2,//
56. "void", //
57. MBeanOperationInfo.INFO, //
58. null//
59. );
60. //////////////////////////////////////////////////////////////////
61. // 最后总合 //
62. //////////////////////////////////////////////////////////////////
63. // create ModelMBeanInfo
64. ModelMBeanInfo mbeanInfo = new ModelMBeanInfoSupport(//
65. RequiredModelMBean.class.getName(), // MBean类
66. null, // 描述文字
67. new ModelMBeanAttributeInfo[] { // 所有的属性信息(数组)
68. nameAttrInfo },//只有一个属性
69. null, // 所有的构造函数信息
70. new ModelMBeanOperationInfo[] { // 所有的操作信息(数组)
71. print1Info,
72. print2Info },//
73. null, // 所有的通知信息(本例无)
74. null//MBean描述子
75. );
76. return mbeanInfo;
77. }
78.}
4、看效果的方法和以前一样,运行HelloAgent,用浏览器打开:http://localhost:8082 。效果图和standard mbean一样
二、总结
我们发现模型Mbean(Model MBean)要比标准MBean(standard mbean)复杂多了,那有什么理由让我们选择使用模型MBean吗?我认为,最大的理由就是模型MBean可以动态配置。试想一下这个应用场景:由于安 全或其他原因,系统要把某个MBean公开的可管理方法隐藏起来。这时,如果你是用标准MBean,这需要修改接口类,然后重新编译发布;如果用 Apache commons-modeler来写的模型MBean,则只需要修改XML文件就行了,不需要重新编译发布(可能要重启一下系统)。这就是模型Mbean 优势之所在了。
细心的人会发现动态MBean和这一节的模型Mbean非常相似,但它们还是有很大不同的:动态MBean没有Hello类,它要自己实现Hello类中的方法逻辑。
这里有个问题:
MBean的属性Name是可读写的,就是说可以对Name进行赋值,但是在运行的界面中对Name赋值后,调用print1Info打印出的信息是"Hello World, null",说明Name属性并没有赋值,不知道该如何正确操作才能正确对Name赋值。