[转]JMX指南(三)
http://www.cnblogs.com/allenny/articles/179163.html
http://www.cnblogs.com/allenny/articles/179200.html
动态MBean
前面讲的标准MBean只能用来管理静态的资源,即所有要管理的资源必须是已知的。但是我们要管理的资源并不是一成不变的,随着时间的变化,我们要管理的资源也会随之而变(例如,管理的范围扩大了)。在这种情况下,标准MBean就不适合我们的要求了。在这种情况下,动态MBean就比较适合我们的要求。动态MBean要管理的资源并不是早就定义好的,而是在运行期才定义的。动态MBean主要利用一些辅助类来完成这个功能,后面的ModelMBean也是如此。所有的动态MBean必须实现javax.management.DynamicMBean 接口。下图是动态MBean的一个结构图。
下面看一下DynamicMBean接口的定义:
package javax.management;
public interface DynamicMBean{
public Object getAttribute( String attribute )throws AttributeNotFoundException, MBeanException,ReflectionException;
public void setAttribute( Attribute attribute )throws AttributeNotFoundException,InvalidAttributeValueException,MBeanException,ReflectionException;
public AttributeList getAttributes( String[] attributes );
public AttributeList setAttributes( AttributeList attributes );
public Object invoke( String actionName, Object[] params,String[] signature ) throws MBeanException,ReflectionExceptionn
public MBeanInfo getMBeanInfo();
}
public interface DynamicMBean{
public Object getAttribute( String attribute )throws AttributeNotFoundException, MBeanException,ReflectionException;
public void setAttribute( Attribute attribute )throws AttributeNotFoundException,InvalidAttributeValueException,MBeanException,ReflectionException;
public AttributeList getAttributes( String[] attributes );
public AttributeList setAttributes( AttributeList attributes );
public Object invoke( String actionName, Object[] params,String[] signature ) throws MBeanException,ReflectionExceptionn
public MBeanInfo getMBeanInfo();
}
上面的前5个方法用于操作属性,方法,构建器等,getMBeanInfo方法用于提供给agent一个关于此MBean的描述,MBeanInfo类是一个基本的辅助类,用于容纳MBean的各种信息。
注意invoke方法:actionName为方法名,params为参数值,signature为参数的类型(例如java,lang.String).
至于辅助类MBeanInfo这里就不说了,还有其他很多辅助类,可以参见jmx规范.
下面看一个简单的动态MBean,这是sun参考实现中的一个例子
import java.lang.reflect.Constructor;
import java.util.Iterator;
import javax.management.*;
/**
* 简单动态MBean - "State"属性:可读可写 - "NbChanges"属性:只读 - "reset()" :方法 注意:动态MBean必须定义一个public的构建器,且必须通过MBeanInfo来管理
*/
public class SimpleDynamic implements DynamicMBean {
public SimpleDynamic() {
// 建立辅助信息
//
buildDynamicMBeanInfo();
}
public Object getAttribute(String attribute_name) throws AttributeNotFoundException, MBeanException, ReflectionException {
// 检查属性是否为空
if (attribute_name == null) {
throw new RuntimeOperationsException(new IllegalArgumentException("Attribute name cannot be null"),
"Cannot invoke a getter of " + dClassName + " with null attribute name");
}
// 检查已知属性,调用已知方法
if (attribute_name.equals("State")) {
return getState();
}
if (attribute_name.equals("NbChanges")) {
return getNbChanges();
}
// 如果属性不可识别,抛出异常
throw (new AttributeNotFoundException("Cannot find " + attribute_name + " attribute in " + dClassName));
}
public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException,
ReflectionException {
if (attribute == null) {
throw new RuntimeOperationsException(new IllegalArgumentException("Attribute cannot be null"), "Cannot invoke a setter of "
+ dClassName + " with null attribute");
}
String name = attribute.getName();
Object value = attribute.getValue();
if (name == null) {
throw new RuntimeOperationsException(new IllegalArgumentException("Attribute name cannot be null"),
"Cannot invoke the setter of " + dClassName + " with null attribute name");
}
if (name.equals("State")) {
if (value == null) {
try {
setState(null);
} catch (Exception e) {
throw (new InvalidAttributeValueException("Cannot set attribute " + name + " to null"));
}
} else {
try {
if ((Class.forName("java.lang.String")).isAssignableFrom(value.getClass())) {
setState((String) value);
} else {
throw (new InvalidAttributeValueException("Cannot set attribute " + name + " to a " + value.getClass().getName()
+ " object, String expected"));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
// 由于"NbChanges" 属性是只读的,所以抛出异常
else if (name.equals("NbChanges")) {
throw (new AttributeNotFoundException("Cannot set attribute " + name + " because it is read-only"));
} else {
throw (new AttributeNotFoundException("Attribute " + name + " not found in " + this.getClass().getName()));
}
}
public AttributeList getAttributes(String[] attributeNames) {
if (attributeNames == null) {
throw new RuntimeOperationsException(new IllegalArgumentException("attributeNames[] cannot be null"),
"Cannot invoke a getter of " + dClassName);
}
AttributeList resultList = new AttributeList();
if (attributeNames.length == 0)
return resultList;
for (int i = 0; i < attributeNames.length; i++) {
try {
Object value = getAttribute((String) attributeNames[i]);
resultList.add(new Attribute(attributeNames[i], value));
} catch (Exception e) {
e.printStackTrace();
}
}
return (resultList);
}