动态MBean是在运行期才定义它的属性和方法,也就是说它有什么属性和方法是可以动态改变的。动态MBean主要利用一些辅助类(构造函数类MBeanConstructorInfo、属性类MBeanAttributeInfo、方法类MBeanOperationInfo)来完成这个功能,所有的动态MBean必须实现DynamicMBean接口。DynamicMBean写好后,使用方法和第一篇文章中普通的MBean一样。
给出一个动态MBean的实例,这个实例最初动态构了一个Name属性及一个print方法,当我们执行它的print方法之后,又给此MBean新增了一个print1方法。实例的代码如下:
1.HelloDynamic
package jmx.dynamicmbean;
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;
/**
* 动态MBean主要利用一些辅助类(构造函数类MBeanConstructorInfo、属性类MBeanAttributeInfo、方法类MBeanOperationInfo)
* 来完成这个功能,所有的动态MBean必须实现DynamicMBean接口
* @author chenyw
*
*/
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
package jmx.dynamicmbean;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import com.sun.jdmk.comm.HtmlAdaptorServer;
/**
* 该类是一个Agent类,说明: 先创建了一个MBeanServer,用来做MBean的容器
* 将Hello这个类注入到MBeanServer中,注入需要创建一个ObjectName类
* 创建一个AdaptorServer,这个类将决定MBean的管理界面,这里用最普通的Html型界面。 AdaptorServer其实也是一个MBean。
* jmx.hello:name=Hello的名字是有一定规则的,格式为:“域名:name=MBean名称”,
* 域名和MBean名称都可以任意取。 打开网页:http://localhost:8082/
* @author chenyw
*
*/
public class HelloAgent {
public static void main(String[] args) throws Exception {
// 创建一个MBeanServer,用来做MBean的容器
MBeanServer server = MBeanServerFactory.createMBeanServer();
ObjectName helloName = new ObjectName("chengang:name=HelloDynamic");
HelloDynamic hello = new HelloDynamic();
// 将Hello这个类注入到MBeanServer中,注入需要创建一个ObjectName类
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还是用得比较少,所谓利器深藏之而不用,非常时方现光芒。
分享到:
相关推荐
1. **MBean定义**:这是用Java类实现的,通常会继承自`javax.management.DynamicMBean`或者实现`javax.management.MBeanInfo`接口。这些类定义了MBean的属性、操作以及它们的行为。 2. **MBean服务器启动**:在`...
Java Management Extensions(JMX)是Java平台上的一个标准技术,用于管理和监控应用程序、操作系统和网络设备。它提供了一种统一的方式来创建、配置、查询和管理Java应用中的资源。本篇文章将深入探讨JMX的核心概念...
2. **动态MBean**:动态MBean不强制实现特定的MBean接口,而是实现`DynamicMBean`接口,它提供了运行时动态暴露属性和操作的能力。 3. **模型MBean**:模型MBean通过元数据描述其属性、操作和通知,这样可以更灵活...
这通常涉及实现`javax.management.MBean`接口或继承`javax.management.DynamicMBean`类,并使用`StandardMBean`包装器。 7. **JMX通知** JMX还支持发布和订阅通知,使得在特定事件发生时,客户端可以收到通知。...
JMX支持四种类型的MBean:Standard MBean、Dynamic MBean、Open MBean和Model MBean。 1. **Standard MBean**:是最简单、最常见的MBean类型,与普通的Java Bean类似,主要用于简单的管理和监控场景。例如,Java的`...
在第四章中我们了解到,MBean不能同时实现自己的MBean接口和DynamicMBean接口,这确保了MBean不能同时是标准和动态的。DynamicMBean接口是一个预定义的标准接口,它允许MBean在运行时描述其管理接口。一个MBean的...
5. **Standard MBeans and Dynamic MBeans**:提供了一套标准的MBean实现,以及动态MBean(DynamicMBean)接口,后者允许对象在运行时自定义其管理接口。 6. **Other Utilities**:可能还包括其他的辅助类和接口,...
2. Dynamic MBeans:也称为DynamicMBean,它们不依赖于预先定义的接口,而是通过`javax.management.DynamicMBean`接口提供动态暴露管理信息。这种类型的MBean更灵活,可以在运行时改变其管理属性和操作。 3. Model ...
它们通过实现`javax.management.DynamicMBean`接口来创建。这类MBean更加灵活,适合于需要在运行时动态调整的应用场景。 - **Model MBeans**:模型MBeans是另一种形式的MBean,它利用反射机制自动创建一个MBean实例...
- **动态 MBean**: 实现 `DynamicMBean` 接口的 MBean,可以动态地添加和删除属性及操作。 2. **MBean 属性**: MBeans 可以包含多种属性,这些属性可以被外部系统读取或修改。 3. **MBean 操作**: MBeans 还可以...
`RequiredModelMBean`类实现了`ModelMBean`接口,而`ModelMBean`接口扩展了`DynamicMBean`接口。但是,与常规Dynamic MBeans不同,Model MBean的管理接口是由管理应用程序或资源外部定义,并通过setter方法插入到...
- **接口实现**:实现 `DynamicMBean` 接口。 - **方法定义**:在运行时动态确定。 #### 七、Spring与JMX的结合 Spring框架为JMX的使用提供了许多便利,主要包括以下几个方面: 1. **简化配置**:Spring通过XML...
这通常涉及到实现`DynamicMBean`接口,该接口提供了一组方法来创建和销毁属性。 ##### 4.3 模型MBeans 模型MBeans提供了最高的灵活性,适用于那些需要自定义属性和操作的对象。实现模型MBeans通常需要使用`Model...
`DynamicMBean`接口是所有动态MBean的基类,通过实现这个接口,可以动态地提供MBean的操作和属性。 3. 开放MBean:开放MBean是一种特殊的动态MBean,它的属性和操作都遵循一种标准的数据类型,这使得它们可以被任何...
2. **实现MBean接口**:MBean类需要实现 javax.management.DynamicMBean 接口或者继承 StandardMBean 类,以便符合JMX规范。 3. **注册MBean**:创建MBeanServer实例,并将MBean注册到MBeanServer中,这样MBean就可...
- **Dynamic MBean**:实现`javax.management.DynamicMBean`接口,管理资源在运行时定义。 - **Model MBean**:使用`javax.management.modelmbean.RequiredModelMBean`,无需编写MBean类,管理资源通常在外部定义...
Java Management Extensions (JMX) 是一个强大的工具,允许监控和管理Java应用程序,包括服务的状态和性能指标。通过实现`javax.management.MBean`接口并注册到MBean服务器,我们可以将服务暴露给管理系统。 最后,...