http://www.blogjava.net/hengheng123456789/articles/66375.htmlhtml
關於動態MBean,能夠參考tomcat BaseModelMBean。tomcat經過配置文件(即每一個組件所在的包下面的mbeans-descriptors.xml)結合通用的動態MBean(org.apache.tomcat.util.modeler.BaseModelMBean)、描述MBean配置信息的org.apache.tomcat.util.modeler.ManagedBean來簡化MBean的構造java
動態MBean是在運行期才定義它的屬性和方法,也就是說它有什麼屬性和方法是能夠動態改變的。動態MBean主要利用一些輔助類(構造函數類MBeanConstructorInfo、屬性類MBeanAttributeInfo、方法類MBeanOperationInfo)來完成這個功能,全部的動態MBean必須實現DynamicMBean接口。DynamicMBean寫好後,使用方法和第一篇文章中普通的MBean同樣。
給出一個動態MBean的實例,這個實例最初動態構了一個Name屬性及一個print方法,當咱們執行它的print方法以後,又給此MBean新增了一個print1方法。實例的代碼以下:apache
import java.lang.reflect.Constructor; import java.util.Iterator; import javax.management.Attribute; import javax.management.AttributeList; import javax.management.DynamicMBean; 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; //實現接口DynamicMBean public class HelloDynamic implements DynamicMBean { //這是咱們的屬性名稱 private String name; private MBeanInfo mBeanInfo = null; private String className; private String description; private MBeanAttributeInfo[] attributes;//屬性類MBeanAttributeInfo private MBeanConstructorInfo[] constructors;//構造函數類MBeanConstructorInfo private MBeanOperationInfo[] operations;//方法類MBeanOperationInfo MBeanNotificationInfo[] mBeanNotificationInfoArray; 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]; mBeanNotificationInfoArray = new MBeanNotificationInfo[0]; } private void buildDynamicMBean() { //設定構造函數 Constructor[] thisconstructors = this.getClass().getConstructors(); constructors[0] = new MBeanConstructorInfo("HelloDynamic(): Constructs a HelloDynamic object", thisconstructors[0]); //設定一個屬性 attributes[0] = new MBeanAttributeInfo("Name", "java.lang.String", "Name: name string.", true, true, false); //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); } //動態增長一個print1方法 private void dynamicAddOperation() { init(); operations = new MBeanOperationInfo[2];//設定數組爲兩個 buildDynamicMBean(); operations[1] = new MBeanOperationInfo("print1", "print1(): print the name", null, "void", MBeanOperationInfo.INFO); mBeanInfo = new MBeanInfo(className, description, attributes, constructors, operations, mBeanNotificationInfoArray); } @Override public Object getAttribute(String attribute_name) { if (attribute_name != null) return null; if (attribute_name.equals("Name")) return name; return null; } @Override public void setAttribute(Attribute attribute) { if (attribute == null) return; 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(); } } @Override public AttributeList getAttributes(String[] attributeNames) { if (attributeNames == null) return null; 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(attributeNames[i]); resultList.add(new Attribute(attributeNames[i], value)); } catch (Exception e) { e.printStackTrace(); } } return resultList; } @Override public AttributeList setAttributes(AttributeList attributes) { if (attributes == null) return null; 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; } @Override 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!"); dynamicAddOperation(); return null; } else if (operationName.equals("print1")) { System.out.println("這是動態增長的一方法print1"); return null; } else { // unrecognized operation name: throw new ReflectionException(new NoSuchMethodException(operationName), "Cannot find the operation " + operationName + " in " + className); } } @Override public MBeanInfo getMBeanInfo() { return mBeanInfo;//MBeanServer由這個方法獲得關鍵的MBean類的構造信息。 } } public class HelloAgent { public static void main(String[] args) throws Exception { MBeanServer server = MBeanServerFactory.createMBeanServer(); ObjectName helloName = new ObjectName("chengang:name=HelloDynamic"); HelloDynamic hello = new HelloDynamic(); server.registerMBean(hello, helloName); ObjectName adapterName = new ObjectName("HelloAgent:name=htmladapter,port=8082"); HtmlAdaptorServer adapter = new HtmlAdaptorServer(); server.registerMBean(adapter, adapterName); adapter.start(); System.out.println("start....."); } }
* 實現於接口DynamicMBean
* 藉助於各類輔助類完成一個類的構造。構造函數類MBeanConstructorInfo、屬性類MBeanAttributeInfo、方法類MBeanOperationInfo
* 這裏全部public方法是實現於DynamicMBean的。主要提供:setAttribute設置屬性、 getAttribute取得屬性、setAttributes設置一組屬性、getAttributes取得一組屬性、invoke方法調用、 getMBeanInfo MBeanServer由這個方法獲得關鍵的MBean類的構造信息。數組
先運行HelloAgent。再打開瀏覽器,輸入網址:http://localhost:8082/。單擊進入「name=HelloDynamic 」項,執行print方法後再回到上一頁面你會發現又多了一個print1方法。
動態MBean的代碼稍顯複雜,但對於一些特殊需求的狀況,它將顯示出強大威力。並且它仍是模型MBeans(Model MBeans)的基礎。不過在通常的項目中,動態MBean仍是用得比較少,所謂利器深藏之而不用,很是時方現光芒。瀏覽器