I. Introduction
Model Mbean is a more practical MBean based on dynamic MBean. If the managed classes are written as standard MBeans, we must implement a set of interfaces with MBean as the suffix for them, so as to increase the code coupling. Based on the Model Mbean, we can manage classes in a dynamic way, such as configuration files. The managed classes can be ordinary classes, which also reduces the coupling of the system.
2, Preparations
1. To manage MBean s in a Web way, we introduced jmxtools.jar
3, Code instance
3.1 configmodel code
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; } }
3.2 configagent code
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"); //Manage MBean s through the Web HtmlAdaptorServer adapter = new HtmlAdaptorServer(); adapter.setPort(8000); server.registerMBean(adapter, adapterName); adapter.start(); System.out.println("adapter start....."); //Manage MBean s through RMI 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....."); } }
3.3 modelmbean code
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"); //attribute ModelMBeanAttributeInfo nameAttrInfo = new ModelMBeanAttributeInfo("ConfigLocation", // Attribute name STRING_CLASS, //Attribute types "luisfigo location", // Descriptive text READABLE, WRITABLE, !IS, // Read and write portAttrDesc ); //Method Descriptor getStateDesc = new DescriptorSupport(new String[] { "name=getConfigLocation", "descriptorType=operation", "class=com.muyu.jmx.ConfigModel", "role=operation" }); // Construct setConfigLocation operation descriptor information 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", "console output configLocation information", 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", "console output configLocation_para information", params, "void", ModelMBeanOperationInfo.INFO, null); ModelMBeanInfo mbeanInfo = new ModelMBeanInfoSupport(// RequiredModelMBean.class.getName(), // Class MBean "ModelMBeanInfoSupport Dynamic MBean", // Descriptive text new ModelMBeanAttributeInfo[] { // All attribute information (array) nameAttrInfo },//Only one attribute null, // All constructor information new ModelMBeanOperationInfo[] { // All operation information (array) getConfigLocation, setConfigLocation, printConfig, printConfig_1},// null, null ); return mbeanInfo; } }
3.4 configclient code
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(); } }
Explanation:
After running ConfigAgent, enter the address in the browser http://localhost:8000/ , click name=configModel, and then carry out the configModel MBean management page. You can perform some operations on configmmbean, which is very similar to the standard MBean introduced in Section 2. Running ConfigClient can discover that MBeans registered in ConfigAgent can be managed through RMI.
Four, summary
The dynamic ModelMBean implements the decoupling between the managed class and JMX. In the ModelMBean class, we can expose some operations and properties. And the client looks like nothing happened. If we use JMX to manage the system, we only need to provide a model MBean such a management class, without destroying the original system code, which really realizes the decoupling between the system and JMX.