JMX管理构件(MBean)分为四种形式,分别是标准管理构件(Standard MBean)、动态管理构件(Dynamic MBean)、开放管理构件(Open Mbean)和模型管理构件(Model MBean)。本文即是对动态管理构件(Dynamic MBean)的演示说明。
动态管理构件的最大的特点是可以在运行期暴露自己的管理接口,因此具有更好的灵活性。它的实现是通过实现一个特定的接口DynamicMBean。
示例参照http://bluestar.iteye.com/blog/58083实现,小作修改,写在此处只为方面查阅。
HelloDynamic,实现了DynamicMBean接口的管理控件(Mbean)
package com.jmxdemo.dynamic; import java.lang.reflect.Constructor; import javax.management.Attribute; import javax.management.AttributeList; import javax.management.AttributeNotFoundException; import javax.management.DynamicMBean; import javax.management.InvalidAttributeValueException; import javax.management.MBeanAttributeInfo; import javax.management.MBeanConstructorInfo; import javax.management.MBeanException; import javax.management.MBeanInfo; import javax.management.MBeanNotificationInfo; import javax.management.MBeanOperationInfo; import javax.management.MBeanParameterInfo; import javax.management.ReflectionException; public class HelloDynamic implements DynamicMBean { // 管理控件(MBean)属性 private String name; // 动态创建MBean需要的变量 private String className = this.getClass().getName(); private String description = "Simple implementation of a dynamic MBean."; private MBeanAttributeInfo[] attributes; private MBeanConstructorInfo[] constructors; private MBeanOperationInfo[] operations; private MBeanInfo mBeanInfo; private MBeanNotificationInfo[] notifications; public HelloDynamic() { init(); buildDynamicMBean(); } private void init() { className = this.getClass().getName(); description = "Simple implementation of a dynamic MBean."; attributes = new MBeanAttributeInfo[1]; constructors = new MBeanConstructorInfo[1]; operations = new MBeanOperationInfo[1]; notifications = new MBeanNotificationInfo[0]; } private void buildDynamicMBean() { // constructors Constructor<?>[] ctors = this.getClass().getConstructors(); constructors[0] = new MBeanConstructorInfo( "HelloDynamic(): Constructs a HelloDynamic object", ctors[0]); // attributes attributes[0] = new MBeanAttributeInfo("name", "java.lang.String", "Name: name string", true, true, false); // methods MBeanParameterInfo[] params = null; operations[0] = new MBeanOperationInfo("print", "print(): print the name", params, "void", MBeanOperationInfo.INFO); // MBeanInfo mBeanInfo = new MBeanInfo(this.className, description, attributes, constructors, operations, notifications); } @Override public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException { if (attribute == null) { return null; } if ("name".equals(attribute)) { return name; } return null; } @Override public AttributeList getAttributes(String[] attributes) { if (attributes == null) { return null; } AttributeList reslist = new AttributeList(); for (String attr : attributes) { try { Object value = getAttribute(attr); reslist.add(new Attribute(attr, value)); } catch (Exception e) { e.printStackTrace(); } } return reslist; } @Override public MBeanInfo getMBeanInfo() { return mBeanInfo; } @Override public Object invoke(String actionName, Object[] params, String[] signature) throws MBeanException, ReflectionException { if (actionName.equals("print")) { print(); } else if("dynamicPrint".equals(actionName)) { dynamicPrint(); } return null; } @Override public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException { if (attribute == null) { return; } String attrname = attribute.getName(); Object attrvalue = attribute.getValue(); if ("name".equals(attrname)) { if (attrvalue == null) { name = null; } else try { if (Class.forName("java.lang.String").isAssignableFrom( attrvalue.getClass())) { name = (String) attrvalue; } } catch (ClassNotFoundException e) { e.printStackTrace(); } } } @Override public AttributeList setAttributes(AttributeList attributes) { if (attributes == null) { return null; } AttributeList reslist = new AttributeList(); for (Object obj : attributes) { Attribute attr = (Attribute) obj; try { setAttribute(attr); String attrname = attr.getName(); Object attrvalue = attr.getValue(); reslist.add(new Attribute(attrname, attrvalue)); } catch (Exception e) { e.printStackTrace(); } } return reslist; } private void print() { System.out.println("Hello " + name + ", This is helloDynamic"); // add method dynamic at runtime operations = new MBeanOperationInfo[2]; buildDynamicMBean(); MBeanParameterInfo[] parameters = null; operations[1] = new MBeanOperationInfo("dynamicPrint", "dynamicPrint: Runtime generated by print method", parameters, "void", MBeanOperationInfo.INFO); } private void dynamicPrint() { System.out.println("This is a runtime generated method!"); } }
HelloDynamicAgent.java
package com.jmxdemo.dynamic; import javax.management.InstanceAlreadyExistsException; import javax.management.MBeanRegistrationException; import javax.management.MBeanServer; import javax.management.MBeanServerFactory; import javax.management.MalformedObjectNameException; import javax.management.NotCompliantMBeanException; import javax.management.ObjectName; import com.sun.jdmk.comm.HtmlAdaptorServer; public class HelloDynamicAgent { private static String DOMAIN = "MyDynamicMBean"; /** * @param args * @throws NullPointerException * @throws MalformedObjectNameException * @throws NotCompliantMBeanException * @throws MBeanRegistrationException * @throws InstanceAlreadyExistsException */ public static void main(String[] args) throws MalformedObjectNameException, NullPointerException, InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException { //创建一个MBean服务对象,DOMAIN类似于java里面的公共package部分 MBeanServer server = MBeanServerFactory.createMBeanServer(DOMAIN); //创建DynamicMBean对象 HelloDynamic hello = new HelloDynamic(); //创建一个web适配器服务器,表示我们MBean服务通过web形式来提供给用户管理 HtmlAdaptorServer htmlserver = new HtmlAdaptorServer(); htmlserver.setPort(9999); //ObjctName对象类似于完整的package ObjectName helloname = new ObjectName(DOMAIN + ":name=HelloDynamic"); ObjectName htmlname = new ObjectName(DOMAIN + ":name=HtmlAdaptor"); server.registerMBean(hello, helloname); server.registerMBean(htmlserver, htmlname); htmlserver.start(); } }
运行程序,打开浏览器,输入http://localhost:9999,即可访问管理页面,页面下方点击name=HelloDynamic,进入MBean View,然后再操作中点击print方法,再次回到MBean View页面你会发现多了一个dynamicPrint方法,这个方法就是我们进行print操作时动态生成的。