[JMX一步步来] 4、动态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."truetruefalse);           //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还是用得比较少,所谓利器深藏之而不用,非常时方现光芒。


1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值