[JMX一步步来] 6、Model Bean

  在上一节是用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赋值。
   

你可能感兴趣的:(apache,bean,xml,浏览器,配置管理)