首    页 建模架构 设计模式 培训咨询 jdon框架 论坛

JMX架构的了解 (MBean部分)

板桥里人 http://www.jdon.com 2003/1/5

我们前章举例的HelloMBean是StandardMBean,这是JMX中的MBean的一种,还有一种 叫DynamicMBean,这是JMX在运行期间能够控制它, 无论哪种MBean,他们的区别只是在他们如何被开发,而不是在它们如何被管理, JMX的Agent提供了处理这两种类型的抽象的处理方法,也就是说,一旦这两种MBean 被JMX的Agent管理,这两种MBean在外界看来没什么区别。

一个标准的standard MBean的Java class是通过它的attributes和operations 被外界管理的,Attributes是内部的一些属性变量,它通过getter 和 setter方法被外界管理 在HelloMBean中,它们是

public String getName();
public void setName(String name);

Operations 是这个class中其它愿意被管理的方法,在HellMBean中是
public void print()

所有这些方法需要在MBean接口中定义,然后通过introspection(内省机制) 显露给一个agent, 上述方法是制造一个可管理资源的最直接办法。

DynamicMBean

而在开发一个DynamicMBean时,attributes 和operations是通过方法调用 间接的显露给agent的。DynamicMBean 适合管理那些已经存在的资源和代码。

需要被JMX的Agent认为是 DynamicMBean,这个Java class或它的子类必须继承 一个DynamicMBean的标准接口。

getMBeanInfo:
DynamicMBean不象StandardMBean那样通过introspection(内省机制)向外界 显露他的attributes和operations,而是通过在运行时,返回这个方法的值来向 外界显露他的attribute names 和 types 以及 operation signatures 。 这个方法返回的是MBeanInfo实例.

getAttribute 和 getAttributes

这是获得相应的attribute name属性名称或属性名称表的值,这个类似StandardMBean的 getter方法,不同点是由调用者提供所需要的属性名,如 public Object getAttribute(String attribute_name) 不同于StandardMBean的getXXXX(Attribute_name)。

setAttribute 和 setAttributes

这个类似StandardMBean的setter方法, 设置相应属性的name-value对。

invoke

invoke方法是让外界来调用DynamicMBean的操作,这儿调用者必须提供 操作名称 作为参数传递的object和这些参数的类型,具体如: public Object invoke(String operationName, Object params[], String signature[])

当DynamicMBean在JMX agent中注册后,DynamicMBean其实就和StandardMBean 是一样的,外界将首先通过getMBeanInfo获得一个管理接口,其中包含attributes 和 operations 名称,然后才将调用DynamicMBean的getters, setters 和invoke方法,

MBean原始类

从上面可以看到,MBean有一些自己规定的诸如MBeanInfo这样的原始类,一共有如下几种:

MBeanInfo - 罗列出所有的属性attribute, 操作operations, 构造器constructor 和 notification

MBeanFeatureInfo - 下面类的子类

MBeanAttributeInfo - 描述一个属性attribute

MBeanConstructorInfo - 描述一个构造器constructor MBean构造器是由签名单独地定义,这个签名是参数的次序和类型.

MBeanOperationInfo - 描述一个操作operation

MBeanParameterInfo - 描述一个操作或构造器的参数

MBeanNotificationInfo - 描述一个notification

通过与使用这些原始类,将你的具体资源就可以动态的嵌入DynamicMBean了.

我们看看下面HelloDynamic程序是如何使用这些原始类构成一个DynamicMBean的:

我们还以上章中的Hello为例,Hello是以Standard MBean来实现了对name的赋值和打印功能.那么通过使用Dynamic MBean我们也来实现这个功能,在这个资源中,有一个属性name以及操作方法print.下面示例展示如何将这个属性和这个操作方法使用DynamicMBean的原始类来实现:

//
import javax.management.*;
import java.lang.reflect.Constructor;
import java.util.Iterator;

/**
* @author Sunny Peng
* @version 1.0
*/

public class HelloDynamic
implements DynamicMBean {

//这是我们的属性名称
private String name = "";

private MBeanInfo mBeanInfo = null;
private String className = this.getClass().getName();
private String description = "Simple implementation of a dynamic MBean.";

private MBeanAttributeInfo[] attributes = new MBeanAttributeInfo[1];
private MBeanConstructorInfo[] constructors = new MBeanConstructorInfo[1];
private MBeanOperationInfo[] operations = new MBeanOperationInfo[1];
MBeanNotificationInfo[] mBeanNotificationInfoArray = new
MBeanNotificationInfo[0];

public HelloDynamic() {

  //设定一个属性
  attributes[0] = new MBeanAttributeInfo("Name",
  "java.lang.String",
  "Name: name string.",
  true,
  true,
  false);

  //设定构造函数
  Constructor[] thisconstructors = this.getClass().getConstructors();
  constructors[0] = new MBeanConstructorInfo(
  "HelloDynamic(): Constructs a HelloDynamic object",
  thisconstructors[0]);

  //operate method 我们的操作方法是print
  MBeanParameterInfo[] params = null;
  operations[0] = new MBeanOperationInfo("print",
  "print(): print the name",
  params,
  "void",
  MBeanOperationInfo.INFO);

  mBeanInfo = new MBeanInfo(className, description, attributes,
  constructors, operations,
  mBeanNotificationInfoArray);

}

public Object getAttribute(String attribute_name) {
  if (attribute_name.equals("Name"))
    return name;
  return null;
}

public AttributeList getAttributes(String[] attributeNames) {
  AttributeList resultList = new AttributeList();

  // if attributeNames is empty, return an empty result list
  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;

}

public void setAttribute(Attribute attribute) {
  String Name = attribute.getName();
  Object value = attribute.getValue();

  try {
    if (Name.equals("Name")) {
    // if null value, try and see if the setter returns any exception
      if (value == null) {
          name = null;
      }
    // if non null value, make sure it is assignable to the attribute
      else if ( (Class.forName("java.lang.String")).isAssignableFrom(
        value.getClass())) {
      {
          name = (String) value;
      }
    }
    }

  }
  catch (Exception e) {
    e.printStackTrace();
  }

}

public AttributeList setAttributes(AttributeList attributes) {
  AttributeList resultList = new AttributeList();

  // if attributeNames is empty, nothing more to do
  if (attributes.isEmpty())
  return resultList;

// for each attribute, try to set it and add to the result list if successfull
  for (Iterator i = attributes.iterator(); i.hasNext(); ) {
    Attribute attr = (Attribute) i.next();
    try {
      setAttribute(attr);
      String name = attr.getName();
      Object value = getAttribute(name);
      resultList.add(new Attribute(name, value));
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }
  return resultList;

}


public Object invoke(String operationName, Object params[],
String signature[]) throws MBeanException,
ReflectionException {

// Check for a recognized operation name and call the corresponding operation
  if (operationName.equals("print")) {
    //具体实现我们的操作方法print
    System.out.println("Hello, " + name + ", this is HellDynamic!");
    return null;
  }else {
    // unrecognized operation name:
    throw new ReflectionException(new NoSuchMethodException(
    operationName),"Cannot find the operation " + operationName + " in " +
      className);
  }

}

public MBeanInfo getMBeanInfo() {
  return mBeanInfo;
}

}

 

 

编制一个HelloAgent来调用这个HelloDynamic:

// java imports
//
import java.util.*;
import java.io.*;
import java.net.*;

// RI imports
//
import javax.management.ObjectName;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.MalformedObjectNameException;

import com.sun.jdmk.comm.HtmlAdaptorServer;

import javax.management.Attribute;
import com.sun.jmx.trace.Trace;


public class HelloAgent {
public HelloAgent() {
}

public static void main(String[] args) {

  // CREATE the MBeanServer
  //
  System.out.println("\n\tCREATE the MBeanServer.");
  MBeanServer server = MBeanServerFactory.createMBeanServer();

  String domain = server.getDefaultDomain();
  ObjectName object_name = null;
  //使用HelloDynamic 如果为Hello 就是使用我们上章介绍的StandardMbean了
  String mbeanName = "HelloDynamic";
  try {
    
    object_name = new ObjectName(domain + ":type=" + mbeanName);

    server.createMBean(mbeanName,object_name);

    Attribute stateAttribute = new Attribute("Name","I am big one");
    server.setAttribute(object_name,stateAttribute);

    String name = (String) server.getAttribute(object_name,"Name");
    System.out.println("name now is "+name);

    server.invoke(object_name,"print",null,null);
  }
  catch (Exception e) {
    System.out.println("\t!!! Could not create the Hello agent !!!");
    e.printStackTrace();
    return;
  }
}

}

直接运行HelloAgent就可以在屏幕输出上得到
"Hello ,I am big one, this is from HelloDynamic"

 

 

 


更多标签...



Jdon框架演示

JiveJdon
源码下载

VIP收费区

历史热点讨论排行榜




google yahoo 新浪ViVi 365Key网摘 天极网摘 CSDN网摘 添加到百度搜藏 POCO网摘





手机 add to google add to yahoo
联系我们 | 关于我们 | 广告联系 | 网站地图 | 设为首页

沪ICP证08026060 如有意见请与我们联系 Powered by JdonFramework
_×
您有新消息