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操作时动态生成的。