動態MBean:DynamicMBean
一、前言
動態MBean是在執行期才定義它的屬性和方法,也就是說它有什麼屬性和方法是可以動態改變的。動態MBean主要利用一些輔助類(建構函式類MBeanConstructorInfo、屬性類MBeanAttributeInfo、方法類MBeanOperationInfo)來完成這個功能,所有的動態MBean必須實現DynamicMBean介面。DynamicMBean寫好後,使用方法和第一篇文章中普通的MBean一樣。
給出一個動態MBean的例項,這個例項最初動態構了一個Name屬性及一個print方法,當我們執行它的print方法之後,又給此MBean新增了一個print1方法。例項的程式碼如下:
二、例項
1、HelloDynamic類
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;
/**
* @author Sunny Peng
* @author change by Chen.Gang, add a feature for dynamic add operation
* @version 1.0
*/
public class HelloDynamic implements DynamicMBean {
//這是我們的屬性名稱
private String name;
private MBeanInfo mBeanInfo = null;
private String className;
private String description;
private MBeanAttributeInfo[] attributes;
private MBeanConstructorInfo[] constructors;
private MBeanOperationInfo[] operations;
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);
}
public Object getAttribute(String attribute_name) {
if (attribute_name != null)
return null;
if (attribute_name.equals("Name"))
return name;
return null;
}
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();
}
}
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;
}
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;
}
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);
}
}
public MBeanInfo getMBeanInfo() {
return mBeanInfo;
}
}
說明:
* 實現於介面DynamicMBean
* 藉助於各種輔助類完成一個類的構造。建構函式類MBeanConstructorInfo、屬性類MBeanAttributeInfo、方法類MBeanOperationInfo
* 這裡所有public方法是實現於DynamicMBean的。主要提供:setAttribute設定屬性、 getAttribute取得屬性、setAttributes設定一組屬性、getAttributes取得一組屬性、invoke方法呼叫、 getMBeanInfo MBeanServer由這個方法得到關鍵的MBean類的構造資訊。
2、HelloAgent類
前面說了HelloDynamic和普通MBean的使用方法是一樣的,因此HelloAgent和第一篇的HelloAgent基本一樣,就是把Hello改成HelloDynamic而已。為了例項完整,也一併帖出來吧。
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import com.sun.jdmk.comm.HtmlAdaptorServer;
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.....");
}
}
3、執行
先執行HelloAgent。再開啟瀏覽器,輸入網址:http://localhost:8082/。單擊進入“name=HelloDynamic ”項,執行print方法後再回到上一頁面你會發現又多了一個print1方法。
4、總結
動態MBean是在執行期才定義它的屬性和方法,也就是說它有什麼屬性和方法是可以動態改變的。動態MBean主要利用一些輔助類(建構函式類MBeanConstructorInfo、屬性類MBeanAttributeInfo、方法類MBeanOperationInfo)來完成這個功能,所有的動態MBean必須實現DynamicMBean介面。DynamicMBean寫好後,使用方法和第一篇文章中普通的MBean一樣。
給出一個動態MBean的例項,這個例項最初動態構了一個Name屬性及一個print方法,當我們執行它的print方法之後,又給此MBean新增了一個print1方法。例項的程式碼如下:
二、例項
1、HelloDynamic類
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;
/**
* @author Sunny Peng
* @author change by Chen.Gang, add a feature for dynamic add operation
* @version 1.0
*/
public class HelloDynamic implements DynamicMBean {
//這是我們的屬性名稱
private String name;
private MBeanInfo mBeanInfo = null;
private String className;
private String description;
private MBeanAttributeInfo[] attributes;
private MBeanConstructorInfo[] constructors;
private MBeanOperationInfo[] operations;
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);
}
public Object getAttribute(String attribute_name) {
if (attribute_name != null)
return null;
if (attribute_name.equals("Name"))
return name;
return null;
}
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();
}
}
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;
}
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;
}
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);
}
}
public MBeanInfo getMBeanInfo() {
return mBeanInfo;
}
}
說明:
* 實現於介面DynamicMBean
* 藉助於各種輔助類完成一個類的構造。建構函式類MBeanConstructorInfo、屬性類MBeanAttributeInfo、方法類MBeanOperationInfo
* 這裡所有public方法是實現於DynamicMBean的。主要提供:setAttribute設定屬性、 getAttribute取得屬性、setAttributes設定一組屬性、getAttributes取得一組屬性、invoke方法呼叫、 getMBeanInfo MBeanServer由這個方法得到關鍵的MBean類的構造資訊。
2、HelloAgent類
前面說了HelloDynamic和普通MBean的使用方法是一樣的,因此HelloAgent和第一篇的HelloAgent基本一樣,就是把Hello改成HelloDynamic而已。為了例項完整,也一併帖出來吧。
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import com.sun.jdmk.comm.HtmlAdaptorServer;
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.....");
}
}
3、執行
先執行HelloAgent。再開啟瀏覽器,輸入網址:http://localhost:8082/。單擊進入“name=HelloDynamic ”項,執行print方法後再回到上一頁面你會發現又多了一個print1方法。
4、總結
動態MBean的程式碼稍顯複雜,但對於一些特殊需求的情況,它將顯示出強大威力。而且它還是模型MBeans(Model MBeans)的基礎。不過在一般的專案中,動態MBean還是用得比較少,所謂利器深藏之而不用,非常時方現光芒。
轉載: http://www.blogjava.net/hengheng123456789/articles/66375.html
相關文章
- Overview (Oracle WebLogic MBean Javadoc) - WLSTViewOracleWebBeanJava
- web server apache tomcat11-16-mbeanWebServerApacheTomcatBean
- Java管理擴充套件指南之MBean簡介Java套件Bean
- java動態代理動態在哪裡?Java
- DLL動態庫動態載入
- 動態改變類結構 & 動態…
- Java動態程式設計---動態代理Java程式設計
- JBOSS 做專案時的問題 有關Jboss, Mbean, Session bean 求助BeanSession
- Linux 依賴動態庫 / 靜態庫的動態態庫 / 靜態庫Linux
- 動態REMREM
- 動態 REMREM
- 動態DNSDNS
- 動態SQLSQL
- 動態棧
- 動態SQL intoSQL
- 動態JSJS
- 動態圖
- 動態代理
- 動態 DP
- 【動態規劃(一)】動態規劃基礎動態規劃
- React Router、And、Redux動態選單和動態路由ReactRedux路由
- Java代理(jdk靜態代理、動態代理和cglib動態代理)JavaJDKCGLib
- 靜態代理和動態代理
- 靜態路由和動態路由路由
- oracle 監聽 靜態 動態Oracle
- 靜態庫與動態庫
- JAVA 靜態代理 & 動態代理Java
- 請問,如何讓jdk1.5的jconsole監聽到mbean server?JDKBeanServer
- Linux下的靜態庫、動態庫和動態載入庫Linux
- Elastic-Job:動態新增任務,支援動態分片AST
- 動態內表及動態ALV顯示(轉)
- 動態SQL——構造通用動態頁面查詢SQL
- oracle procedure plsql 動態sql之動態傳遞表OracleSQL
- BootStrap的動態模態框及靜態模態框boot
- MyBatis 動態 SQLMyBatisSQL
- JDK動態代理JDK
- Flask動態路由Flask路由
- RDLC 動態列