动态MBean

standard MBean适合管理新资源或未知,静态资源。随着资源演进,API会随着每次发布而改变。Dynamic MBean则比较适合处理这种情况,因为它在运行时决定管理接口。Dynamic MBean使用class元数据来描述管理接口。
JMX agent识别Dynamic MBean,是因为它们必须实现javax.management.DynamicMBean接口。

 

[java][/java] view plaincopyprint?

  1. package javax.management;
  2. public interface DynamicMBean{
  3.     public Object getAttribute( String attribute )
  4.          throws AttributeNotFoundException, MBeanException,
  5.          ReflectionException;
  6.     public void setAttribute( Attribute attribute )
  7.          throws AttributeNotFoundException,
  8.          InvalidAttributeValueException,MBeanException,
  9.          ReflectionException;
  10.     public AttributeList getAttributes( String[] attributes );
  11.     public AttributeList setAttributes( AttributeList attributes );
  12.     public Object invoke( String actionName, Object[] params,String[] signature )
  13.          throws MBeanException,ReflectionExceptionn
  14.     public MBeanInfo getMBeanInfo();
  15. }

 

DynamicMBean接口使用MBeanInfo类的方式暴露资源的管理接口。JMX agent使用getMBeanInfo()方法来获取Dynamic MBean管理接口描述。MBeanInfo对象是standard JMX对象(描述MBean管理接口的各部分)的容器。

getAttribute()方法返回类型为Object对象,它简单的封装了暴露的属性实际的值。getAttributes()返回AttributeList类,它是ArrayList的一个子类,是Attribute对象的集合。每个Attribute对象封装了attribute的名称和值。
invoke()方法有三个参数:string,方法的名称。Object的数组(方法的参数值)和string数组(参数类型的字符串)

MBeanInfo类是描述MBean管理接口对象容器。MBean的元数据类被Dynamic MBean、MBean server创建。MBean server内部使用这些对象(不用区分MBean类型)。

MBeanFeatureInfo是所有metaclass的基类,MBeanParameterInfo是辅助类。每个MBean元数据类是MBeanFeatureInfo的子类,它包含一个name和description。MBeanParameterInfo提供了构造器或操作的参数描述。

[java][/java] view plaincopyprint?

  1. public MBeanConstructorInfo( String description,
  2.        java.lang.reflect.Constructor constructor );
  3. public MBeanConstructorInfo( String name, String description,
  4.        MBeanParameterInfo[] signature )
  5. public MBeanAttributeInfo( String name, String description,
  6.        java.lang.reflect.Method getter,
  7.        java.lang.reflect.Method setter)
  8. public MBeanAttributeInfo( String name, String type, String
  9.        description, boolean isReadable,
  10.        boolean isWritable, boolean isIs)

MBeanAttributeInfo的getType()方法返回属性的类型,isReadable()属性是否可读,isWritable()属性是否可写,isIs()。

[java][/java] view plaincopyprint?

  1. public MBeanOperationInfo( String description,
  2.        java.lang.reflect.Method method)
  3. public MBeanOperationInfo( String name, String description,
  4.        MBeanParameterInfo[] signature,
  5.        String type, int impact)

 

MBeanOperationInfo定义了public static final成员变量,这些值描述了invoke的特定操作的impact。
INFO:操作返回信息
ACTION:操作导致MBean的变更或action。
ACTION_INFO:操作导致INFO和ACTION的影响。
UNKNOW:未知的。

构建Dynamic MBean的MBeanInfo信息:

 

[java][/java] view plaincopyprint?

  1. private void buildDynamicMBean() {
  2.         // 设定构造函数
  3.         Constructor[] thisconstructors = this.getClass().getConstructors();
  4.         constructors[0] = new MBeanConstructorInfo(
  5.                 “HelloDynamic(): Constructs a HelloDynamic object”,
  6.                 thisconstructors[0]);
  7.         // 设定一个属性
  8.         attributes[0] = new MBeanAttributeInfo(“Name”, “java.lang.String”,
  9.                 “Name: name string.”, true, true, false);
  10.         // operate method 我们的操作方法是print
  11.         MBeanParameterInfo[] params = null;// 无参数
  12.         operations[0] = new MBeanOperationInfo(“print”,
  13.                 “print(): print the name”, params, “void”,
  14.                 MBeanOperationInfo.INFO);
  15.         mBeanInfo = new MBeanInfo(className, description, attributes,
  16.                 constructors, operations, mBeanNotificationInfoArray);
  17.     }

方法调用:

[java][/java] view plaincopyprint?

  1. public Object invoke(String actionName, Object[] params, String[] signature)
  2.             throws MBeanException, ReflectionException {
  3.         if (actionName.equals(“print”)) {
  4.             // 具体实现我们的操作方法print
  5.             System.out.println(“Hello, ” + name + “, this is HellDynamic!”);
  6.             dynamicAddOperation();
  7.             return null;
  8.         } else if (actionName.equals(“print1”)) {
  9.             System.out.println(“这是动态增加的一方法print1”);
  10.             return null;
  11.         } else {
  12.             // unrecognized operation name:
  13.             throw new ReflectionException(
  14.                     new NoSuchMethodException(actionName),
  15.                     “Cannot find the operation ” + actionName + ” in “
  16.                             + className);
  17.         }
  18.     }

标签