JMX Dynamic MBean

    The second MBean I want to bring in is the Dynamic MBean, the main purpose of using Dynamic MBean is that your management interface varies very often, just think of a simplest case, we have a managed resource about the Person's information, and now we can set and get the firstName and lastName of a certain person thro jmx and it works fine, but one day, your boss tell you that we should provide the address info of the person too, if we're using the Standard MBean, what should we do? We have to modify the interface and add the implementations for added methods, don't we?It would be a mess of work when this kind of situation happens often, especially when the Standard MBean's management interface consists of many predefined interfaces which is prone to be changed later. And Dynamic MBean can ease this kind of situation(Although Dynamic MBean can ease this situation, it also has some limitations, which will be covered in Model MBean blog entry).

 

     Recall from the Standard MBean article, its management interface is made of some predefined interface the MBean implements, while Dynamic MBean forms its management interface by its metadata, a MBeanInfo.That's why the Dynamic MBean interface defines a 'getMBeanInfo()' method. Now let's take a look at the Dynamic MBean interface.


JMX Dynamic MBean_第1张图片
 

    There is a limitation about MBeas is that a MBean can not be both Standard and Dynamic, that is to say, a MBean can not implements the Standard interface and the Dynamic interface at the same time. As we previously described, the management interface is nothing but a group of attributes and operations, and that is why Dynamic MBean interface defines methods such as getAttribute(), setAttribute().

 

    Since we all know that the Daynamic MBean's management interface is defined at runtime, so, you would like to examine the MBeanInfo in Dynamic MBean, and see how it make up the management interface.

   
JMX Dynamic MBean_第2张图片


   MBeanFeatureInfo is the super class of all the other mbean metadatas. And from their names, we could easily infer their purposes, for example MBeanOperationInfo correponds to the operations defined in the manageable resource and the MBeanAttributeInfo corresponds to the attributes of your manageable resource. Although they are easy to understand, I still like to walk you through them one by one.

   Speaking of MBeanFeatureInfo, since it's the super class of all the other mbean metadatas, it only defines two attributes that need us to be awared of.

  • name->what does it stand for depends on the metadata type, if the metadata type is method-related, such as MBeanOperationInfo or MBeanConstructorInfo, then the name here indicates a method name, if the metadata type is attribute-related like MBeanParamenterInfo or MBeanAttributeInfo, then it indicates a attribute name.
  • description->a custom text which is used to describe what is this metadata for or something like that.

   MBeanParameterInfo, a parameter wrapper which is used in MBeanOperationInfo or MBeanConstructorInfo. You can create it in the following two ways:

 public MBeanParameterInfo(String name, String type,String description)

 public MBeanParameterInfo(String name,String type,String description,Descriptor descriptor)

    We'll avoid Descriptor class here, since it will be covered in Model MBean article. Here just think of it as an object that can hold some additional infos.

  •     type->the parameter type of course, for example, for parameter 'String name', its type is 'java.lang.String'

    MBeanOperationInfo, it encapsulates an operation exposed by an MBean, a method wrapper.The following are its two constructors:

   

public MBeanOperationInfo(String description, Method method);

public MBeanOperationInfo(String name,
			      String description,
			      MBeanParameterInfo[] signature,
			      String type,
			      int impact)
  • type->indicates the type of the return value of this method.
  • impact->there are four values for this argument,INFO,ACTION,ACTION_INFO and UNKNOWN.INFO means this operation can return information, ACTION indicates the operation could change the state of MBean without returning information, ACTION_INFO indicates the operation not only change the state of MBean but also return information, and UNKNOWN indicates an unknown operation.

   

    MBeanAttributeInfo, it can encapsulates an attribute of MBean, just like the other metadata, you can construct it in the following ways:

   

public MBeanAttributeInfo(String name,
			      String type,
			      String description,
			      boolean isReadable,
			      boolean isWritable,
			      boolean isIs)

 public MBeanAttributeInfo(String name,
			      String type,
			      String description,
			      boolean isReadable,
			      boolean isWritable,
			      boolean isIs,
                              Descriptor descriptor)
  • type->the type of attribute, like the one in MBeanParameterInfo.
  • isReadable->indicates whether it is readable or not.
  • isWritable->indicates whether it is writable or not.
  • isIs->indicates whether this attribute starts with 'is' or not, in the meantime, this attribute has to be a boolean type.

     MBeanConstructorInfo, a constructor wrapper, you can create it by using its two constructors:

  

public MBeanConstructorInfo(String description, Constructor constructor)

 public MBeanConstructorInfo(String name, 
			String description,
			MBeanParameterInfo[] signature)

  

   MBeanNotificationInfo, a metadata class that describes the notifications the MBean can emit. Nothing special and like the other metadata classes, it has two constructors:

  

public MBeanNotificationInfo(String[] notifTypes,
				 String name,
				 String description)

public MBeanNotificationInfo(String[] notifTypes,
			 String name,
			 String description,
                                 Descriptor descriptor)

 

   After examining the Dynamic MBean interface and its metadata classes, it is time for some concrete examples to combine them together. We often implement the Dynamic MBean by using javabean introspection, if you have experience of java reflection, you'll find that there are no fancy codes at all in the following codes.

  

public class DynamicImpl implements DynamicMBean {

	public Object getAttribute(String attribute)
			throws AttributeNotFoundException, MBeanException,
			ReflectionException {

		try {
			Field attr = this.getClass().getDeclaredField(attribute);
			// this make the private attribute accessible
			attr.setAccessible(true);
			return attr.get(this);
		} catch (Exception e) {
			// eatting all
		}
		return null;
	}

	public AttributeList getAttributes(String[] attributes) {
		AttributeList attrList = new AttributeList();
		try {
			Attribute attribute = null;
			for (String attr : attributes) {
				attribute = new Attribute(attr, getAttribute(attr));
				attrList.add(attribute);
			}
		} catch (Exception e) {
			// eatting all
		}
		return attrList;
	}

	public Object invoke(String actionName, Object[] params, String[] signature)
			throws MBeanException, ReflectionException {
		try {
			// first, constructing the param types
			Class[] paramTypes = new Class[signature.length];
			int i = 0;
			for (String sig : signature) {
				paramTypes[i++] = this.getClass().getClassLoader().loadClass(
						sig);
			}

			// find the method and invoke it
			Method md = this.getClass().getMethod(actionName, paramTypes);
			return md.invoke(this, params);
		} catch (Exception e) {
			// eatting all
		}
		return null;
	}

	public void setAttribute(Attribute attribute)
			throws AttributeNotFoundException, InvalidAttributeValueException,
			MBeanException, ReflectionException {
		try {
			Field attr = this.getClass().getDeclaredField(attribute.getName());
			// this make the private attribute accessible
			attr.setAccessible(true);
			attr.set(this, attribute.getValue());
		} catch (Exception e) {
			// eatting all
		}
	}

	public AttributeList setAttributes(AttributeList attributes) {
		try {
			Attribute attribute = null;
			for (int i = 0; i < attributes.size(); i++) {
				attribute = (Attribute) attributes.get(i);
				setAttribute(attribute);
			}
		} catch (Exception e) {
			// eatting all
		}
		return attributes;
	}

	public MBeanInfo getMBeanInfo() {
		// exposes the attribute name
		MBeanAttributeInfo attributeInfo = new MBeanAttributeInfo("name",
				"java.lang.String", "name exposed", true, true, false);

		// exposes the printName operation
		MBeanOperationInfo operationInfo = new MBeanOperationInfo("printName",
				"pring name info ", new MBeanParameterInfo[0], "void", 2);

		return new MBeanInfo("DynamicImpl",
				"The manageable resource is DynamicImpl",
				new MBeanAttributeInfo[] { attributeInfo },
				new MBeanConstructorInfo[0],
				new MBeanOperationInfo[] { operationInfo },
				new MBeanNotificationInfo[0]);
	}

	private String name;

	public void printName() {
		System.out.println("name->" + name);
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}

 

   When you finish your Dynamic MBean, register it to the MBean Server and enjoy it.

 

你可能感兴趣的:(Blog,UP,idea)