【JMX】5. 模型MBean

复习

一共有四种MBean:

  1. 标准MBeans(Standard MBeans)设计和实现是最简单的,这类MBean使用自己的方法名作为管理接口;——在前一篇中的Hello、HelloMBean就是一个标准MBeans(Standard MBeans)
  2. 动态MBeans(Dynamic MBeans)必须实现一个指定的接口,由于动态MBeans在运行期间暴露它们的管理接口,因此更为灵活;
  3. 开放MBeans(Open MBeans)属于动态MBeans,这类MBean依靠基础数据类型来实现通用管理,并为友情用户进行自我声明;
  4. 模型MBeans(Model MBeans)同样也是动态MBeans,这类MBeans是完全可配置的,在运行期间进行自我声明;它们为资源动态工具提供一个一般性的,有默认行为的MBeans类。

1)编写MBean

与动态MBean相同,不用实现任何接口:

public class Hello { 
    private String name;     
    public String getName() {   
        return name;   
    }     
    public void setName(String name) {   
        this.name = name;   
    }     
    public void printHello() {   
        System.out.println("Hello World, " + name);   
    }     
    public void printHello(String whoName) {   
        System.out.println("Hello , " + whoName);   
    }   
}  

2)编写Agent

和以前就差一句:把“new Hello()”这一句删除了,加上了ModelMbeanUtils.createModlerMbean();

public class HelloAgent {   
    public static void main(String[] args) throws Exception {   
        MBeanServer server = MBeanServerFactory.createMBeanServer();   
        ObjectName helloName = new ObjectName("chengang:name=HelloWorld");   
        //Hello hello = new Hello();   
        RequiredModelMBean hello = ModelMBeanUtils.createModlerMBean();   //ModelMBeanUtils是自己编写的类!
        server.registerMBean(hello, helloName);   
        ObjectName adapterName = new ObjectName("HelloAgent:name=htmladapter,port=8082");   
        HtmlAdaptorServer adapter = new HtmlAdaptorServer();   
        server.registerMBean(adapter, adapterName);   
        adapter.start();   
        System.out.println("start.....");   
    }   
}   

3)编写ModelMbeanUtils

public class ModelMBeanUtils {   
    private static final boolean READABLE = true;   
    private static final boolean WRITABLE = true;   
    private static final boolean BOOLEAN = true;   
    private static final String STRING_CLASS = "java.lang.String";   
    public static RequiredModelMBean createModlerMBean() {   
        RequiredModelMBean model = null;   
        try {   
            model = new RequiredModelMBean();   
            
            model.setManagedResource(new Hello(), "ObjectReference");   
            ModelMBeanInfo info = createModelMBeanInfo();   
            model.setModelMBeanInfo(info);   
        } catch (Exception e) {   
            e.printStackTrace();   
        }   
        return model;   
    }   
    private static ModelMBeanInfo createModelMBeanInfo() {   
        //////////////////////////////////////////////////////////////////   
        //                        属性                                        //   
        //////////////////////////////////////////////////////////////////   
        // 构造name属性信息   -----好像没生效?打印的是null----------------
        ModelMBeanAttributeInfo nameAttrInfo = new ModelMBeanAttributeInfo(//   
                "Name", // 属性名          
                STRING_CLASS, //属性类型       
                "people name", // 描述文字         
                READABLE, WRITABLE, !BOOLEAN, // 读写         
                null // 属性描述子   
        );   
        //////////////////////////////////////////////////////////////////   
        //                        方法                                        //   
        //////////////////////////////////////////////////////////////////   
        //构造 printHello()操作的信息          
        ModelMBeanOperationInfo print1Info = new ModelMBeanOperationInfo(//   
                "printHello", //   
                null, //     
                null, //   
                "void", //     
                MBeanOperationInfo.INFO, //       
                null //   
        );   
        // 构造printHello(String whoName)操作信息        
        ModelMBeanOperationInfo print2Info;   
        MBeanParameterInfo[] param2 = new MBeanParameterInfo[1];   
        param2[0] = new MBeanParameterInfo("whoName", STRING_CLASS, "say hello to who");   
        print2Info = new ModelMBeanOperationInfo(//   
                "printHello", //   
                null,//   
                param2,//   
                "void", //   
                MBeanOperationInfo.INFO, //   
                null//   
        );   
        //////////////////////////////////////////////////////////////////   
        //                        最后总合                                    //   
        //////////////////////////////////////////////////////////////////   
        // create ModelMBeanInfo          
        ModelMBeanInfo mbeanInfo = new ModelMBeanInfoSupport(//   
                RequiredModelMBean.class.getName(), // MBean类   
                null, // 描述文字        
                new ModelMBeanAttributeInfo[] { // 所有的属性信息(数组)   
                nameAttrInfo },//只有一个属性   
                null, // 所有的构造函数信息     
                new ModelMBeanOperationInfo[] { // 所有的操作信息(数组)   
                        print1Info,   
                        print2Info },//   
                null, // 所有的通知信息(本例无)   
                null//MBean描述子   
        );   
        return mbeanInfo;   
    }   
}   

它主要是返回一个RequiredModelMBean类,此类主要包括了一个ModelMBeanInfo类的信息。在 ModelMBeanInfo中定义了所有对需要管理的属性和方法的描述。


4)运行

和标准MBean效果基本一样


5)总结

我们发现模型Mbean(Model MBean)要比标准MBean(standard mbean)复杂多了,那有什么理由让我们选择使用模型MBean吗?

我认为,最大的理由就是模型MBean可以动态配置。试想一下这个应用场景:由于安全或其他原因,系统要把某个MBean公开的可管理方法隐藏起来。这时,如果你是用标准MBean,这需要修改接口类,然后重新编译发布;如果用 Apache commons-modeler来写的模型MBean,则只需要修改XML文件就行了,不需要重新编译发布(可能要重启一下系统)。这就是模型Mbean 优势之所在了。
 

与动态MBean的区别:
 细心的人会发现动态MBean和这一节的模型Mbean非常相似,但它们还是有很大不同的:动态MBean没有Hello类,它要自己实现Hello类中的方法逻辑。




你可能感兴趣的:(jmx)