[探究JMX] 5、动态模型MBean

一、简介

      Model MBean是基于DynamicMBean的更实用的MBean,如果编写被管理的类为标准MBean,我们必须为它们实现一套以MBean为后缀名的接口,这样使代码的耦合度增高。而基于Model Mbean,我们可以用配置文件等动态的方式来管理类,被管理的类可以是普通的类,这样也降低了系统的耦合性。

 

二、准备工作

 

      1、为了Web方式管理MBean,我们引入jmxtools.jar

 

三、代码实例

 

package com.muyu.jmx;

public class ConfigModel {

    private String configLocation;

    public String getConfigLocation() {
        return configLocation;
    }

    public void printConfigLocation() {
        System.out.println(configLocation);
    }

    public void printConfigLocation(String i_ConfigLocation) {
        System.out.println(i_ConfigLocation);
    }

    public void setConfigLocation(String configLocation) {
        this.configLocation = configLocation;
    }
}


 

package com.muyu.jmx;

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import javax.management.modelmbean.RequiredModelMBean;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;

import com.sun.jdmk.comm.HtmlAdaptorServer;

public class ConfigAgent {
    public static void main(String[] args) throws Exception {    
        MBeanServer server = MBeanServerFactory.createMBeanServer();    
        ObjectName configName = new ObjectName("LuisFigo:name=configModel");    
        RequiredModelMBean config = ModelMBean.createModelMBean();  
        server.registerMBean(config, configName);      
        ObjectName adapterName = new ObjectName("HelloAgent:name=htmladapter,port=8000");
        
        //通过Web来管理MBean
        HtmlAdaptorServer adapter = new HtmlAdaptorServer();      
        adapter.setPort(8000);
        server.registerMBean(adapter, adapterName);        
        adapter.start();  
        System.out.println("adapter start.....");    
        
        //通过RMI方式来管理MBean
        Registry registry = LocateRegistry.createRegistry(9999);
        JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/mserver");        
        JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, server); 

        cs.start();
        System.out.println("rmi start.....");
     }
}

 

package com.muyu.jmx;

import javax.management.Attribute;
import javax.management.AttributeNotFoundException;
import javax.management.Descriptor;
import javax.management.InstanceNotFoundException;
import javax.management.InvalidAttributeValueException;
import javax.management.MBeanException;
import javax.management.MBeanParameterInfo;
import javax.management.ReflectionException;
import javax.management.RuntimeOperationsException;
import javax.management.modelmbean.DescriptorSupport;
import javax.management.modelmbean.InvalidTargetObjectTypeException;
import javax.management.modelmbean.ModelMBeanAttributeInfo;
import javax.management.modelmbean.ModelMBeanInfo;
import javax.management.modelmbean.ModelMBeanInfoSupport;
import javax.management.modelmbean.ModelMBeanOperationInfo;
import javax.management.modelmbean.RequiredModelMBean;

public class ModelMBean {

    private static final boolean READABLE = true;
    private static final boolean WRITABLE = true;
    private static final boolean IS = true;
    private final static String STRING_CLASS = "java.lang.String";
    
    public static RequiredModelMBean createModelMBean() throws RuntimeOperationsException,
            MBeanException, InstanceNotFoundException, InvalidTargetObjectTypeException, AttributeNotFoundException, InvalidAttributeValueException, ReflectionException {
        RequiredModelMBean modelMBean = null;
        modelMBean = new RequiredModelMBean();
        modelMBean.setManagedResource(new ConfigModel(), "ObjectReference");
        ModelMBeanInfo info = createModelMBeanInfo();
        modelMBean.setModelMBeanInfo(info);
        modelMBean.setAttribute(new Attribute("ConfigLocation", "test initial"));
        return modelMBean;
    }
    
    public static ModelMBeanInfo createModelMBeanInfo() {
        
        Descriptor portAttrDesc = new DescriptorSupport();
        portAttrDesc.setField("name", "ConfigLocation");
        portAttrDesc.setField("descriptorType", "attribute");
        portAttrDesc.setField("displayName", "ConfigLocation");
        portAttrDesc.setField("getMethod", "getConfigLocation");
        portAttrDesc.setField("setMethod", "setConfigLocation");
        
        //属性
        ModelMBeanAttributeInfo nameAttrInfo = new ModelMBeanAttributeInfo("ConfigLocation", // 属性名        
                STRING_CLASS, //属性类型     
                "luisfigo location", // 描述文字       
                READABLE, WRITABLE, !IS, // 读写       
                portAttrDesc
        );
        //方法
        Descriptor getStateDesc = new DescriptorSupport(new String[] {
                "name=getConfigLocation", "descriptorType=operation", "class=com.muyu.jmx.ConfigModel",
                "role=operation" });
        // 构造 setConfigLocation操作描述符信息
        Descriptor setStateDesc = new DescriptorSupport(new String[] {
          "name=setConfigLocation", "descriptorType=operation", "class=com.muyu.jmx.ConfigModel",
          "role=operation" });
        ModelMBeanOperationInfo getConfigLocation = new ModelMBeanOperationInfo(
                                                                      "getConfigLocation",
                                                                      "get configLocation attribute",
                                                                      null,
                                                                      "java.lang.String",
                                                                      ModelMBeanOperationInfo.ACTION,
                                                                      getStateDesc
                                                                    );
        MBeanParameterInfo[] setStateParms = new MBeanParameterInfo[] { (new MBeanParameterInfo(
                                                                                                "configLocation_para", "java.lang.String", "new configLocation value")) };
        ModelMBeanOperationInfo setConfigLocation = new ModelMBeanOperationInfo(
                                                                      "setConfigLocation",
                                                                      "set configLocation attribute",
                                                                      setStateParms,
                                                                      "void",
                                                                      ModelMBeanOperationInfo.ACTION,
                                                                      setStateDesc
                                                                    ); 

        ModelMBeanOperationInfo printConfig = new ModelMBeanOperationInfo("printConfigLocation", "控制台输出configLocation信息",
                                                                          null, "void", ModelMBeanOperationInfo.INFO, null);
        ModelMBeanOperationInfo printConfig_1 = null;
        MBeanParameterInfo[] params = new MBeanParameterInfo[1];
        params[0] = new MBeanParameterInfo("i_ConfigLocation", STRING_CLASS, "Hello , I am LuisFigo");
        printConfig_1 = new ModelMBeanOperationInfo("printConfigLocation", "控制台输出configLocation_para信息",
                                                  params, "void", ModelMBeanOperationInfo.INFO, null);
        
        ModelMBeanInfo mbeanInfo = new ModelMBeanInfoSupport(//
                                                             RequiredModelMBean.class.getName(), // MBean类
                                                             "ModelMBeanInfoSupport Dynamic MBean", // 描述文字      
                                                             new ModelMBeanAttributeInfo[] { // 所有的属性信息(数组) 
                                                             nameAttrInfo },//只有一个属性 
                                                             null, // 所有的构造函数信息   
                                                             new ModelMBeanOperationInfo[] { // 所有的操作信息(数组)
                                                                 getConfigLocation,
                                                                 setConfigLocation,
                                                                 printConfig,
                                                                 printConfig_1},//
                                                             null, 
                                                             null
                                                     );
                                                     return mbeanInfo;

    }
}

 

package com.muyu.jmx;

import java.io.IOException;
import java.util.Iterator;
import java.util.Set;

import javax.management.Attribute;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.InvalidAttributeValueException;
import javax.management.MBeanException;
import javax.management.MBeanServerConnection;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

public class ConfigClient {
    
    public static void main(String[] args) throws IOException, MalformedObjectNameException, NullPointerException, InstanceNotFoundException, MBeanException, ReflectionException, AttributeNotFoundException, InvalidAttributeValueException {
        JMXServiceURL url = new JMXServiceURL(
        "service:jmx:rmi:///jndi/rmi://localhost:9999/mserver");
        JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
        MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();

        Set names = mbsc.queryNames(null, null);
        for (Iterator i = names.iterator(); i.hasNext();) {
            System.out.println("\tObjectName = " + (ObjectName) i.next());
        }

        ObjectName stdMBeanName = new ObjectName("LuisFigo:name=configModel");

        mbsc.invoke(stdMBeanName, "printConfigLocation", new String[]{"helloworld"}, new String[]{"java.lang.String"});
        mbsc.setAttribute(stdMBeanName, new Attribute("ConfigLocation", "LuisFigo, this is a new configLocation"));
        mbsc.invoke(stdMBeanName, "printConfigLocation", null, null);
        jmxc.close();
    }
    
}

 

 

说明:

      运行ConfigAgent后,在浏览器里输入地址http://localhost:8000/,点击name=configModel后进行configModel MBean管理页面,可以对configMBean进行一些操作,同第二节介绍的标准MBean很相似。运行ConfigClient可以发现,通过RMI可以管理ConfigAgent中注册的MBean。

 

四、总结

      动态ModelMBean实现了被管理类与JMX的解耦,在ModelMBean类里我们可以暴露一些操作和属性。而客户端看起来像什么事都没有发生一样。如果采用JMX来管理系统的话,我们只需要提供一个ModelMBean这样一个管理类就可以,而不需要破坏原来的系统代码,真正实现了系统与JMX的解耦。

 

 

你可能感兴趣的:(Web,浏览器,配置管理,sun)