欢迎支持笔者新作:《深入理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客。


欢迎跳转到本文的原文链接:https://honeypps.com/java/jmx-quick-start-3-model-mbean/

Model MBean

相对于Standard MBean,Model MBean更加灵活。如果我们不能修改已有的Java类,那么使用Model MBean是不错的选择。

Model MBean也是一种专门化的动态管理构件。它是预制的、通用的和动态的 MBean 类,已经包含了所有必要缺省行为的实现,并允许在运行时添加或覆盖需要定制的那些实现。JMX规范规定该类必须实现为javax.management.modelmbean.RequiredModelMBean,管理者要做的就是实例化该类,并配置该构件的默认行为并注册到JMX代理中,即可实现对资源的管理。JMX代理通过获得一个ModelMBeanInfo对象来获取管理接口。
模型管理构件具有以下新的特点:

  • 持久性。定义了持久机制,可以利用Java的序列化或JDBC来存储模型MBean的状态。 就是要保存到硬盘上。
  • 通知和日志功能。能记录每一个发出的通知,并能自动发出属性变化通知。
  • 属性值缓存。具有缓存属性值的能力。

还是沿用前面的代码,但是这里就不需要类似HelloMBean这样的接口了。

package com.test.jmx.modelBean;public class Hello { //注意这里没有implements任何东西private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}public void printHello(){System.out.println("Hello world, "+name);}public void printHello(String whoName){System.out.println("Hello, "+whoName);}
}

但是需要自己编写一个产生Model MBean的工具类。Model MBean使用JDK提供的RequiredModelMBean,指定基本的Bean(Hello),创建好需要的ModelMBeanInfo就可以了。

package com.test.jmx.modelBean;import javax.management.*;
import javax.management.modelmbean.*;/*** Created by hidden on 2016/10/9.*/
public class ModelMBeanUtils {private static final boolean READABLE = true;private static final boolean WRITABLE = true;private static final boolean BOOLEAN = true;private static final String STRING_CLASS = "java.lang.String";public static RequiredModelMBean createModelerMBean() {RequiredModelMBean model = null;try {model = new RequiredModelMBean();model.setManagedResource(new Hello(), "ObjectReference");ModelMBeanInfo info = createModelMBeanInfo();model.setModelMBeanInfo(info);} catch (Exception e) {e.printStackTrace();}return model;}private static ModelMBeanInfo createModelMBeanInfo() {////                        属性                                        ////// 构造name属性信息Descriptor portAttrDesc = new DescriptorSupport();portAttrDesc.setField("name", "Name");portAttrDesc.setField("descriptorType", "attribute");portAttrDesc.setField("displayName", "Name");portAttrDesc.setField("getMethod", "getName");portAttrDesc.setField("setMethod", "setName");ModelMBeanAttributeInfo nameAttrInfo = new ModelMBeanAttributeInfo(//"Name", // 属性名STRING_CLASS, //属性类型"people name", // 描述文字READABLE, WRITABLE, !BOOLEAN, // 读写portAttrDesc // 属性描述);////                        方法                                        ////// 构造 getName操作描述符信息Descriptor getStateDesc = new DescriptorSupport(new String[] {"name=getName","descriptorType=operation","class=com.test.jmx.modelBean.Hello","role=operation"});ModelMBeanOperationInfo getName = new ModelMBeanOperationInfo(//"getName", //"get name attribute", //null, //"java.lang.String", //MBeanOperationInfo.ACTION, //getStateDesc //);// 构造 setName操作描述符信息Descriptor setStateDesc = new DescriptorSupport(new String[] {"name=setName", "descriptorType=operation", "class=com.test.jmx.modelBean.Hello","role=operation" });MBeanParameterInfo[] setStateParms = new MBeanParameterInfo[] { (new MBeanParameterInfo("name", "java.lang.String", "new name value")) };ModelMBeanOperationInfo setName = new ModelMBeanOperationInfo(//"setName", //"set name attribute", //setStateParms, //"void", //MBeanOperationInfo.ACTION, //setStateDesc //);//构造 printHello()操作的信息ModelMBeanOperationInfo print1Info = new ModelMBeanOperationInfo(//"printHello", //null, //null, //"void", //MBeanOperationInfo.INFO, //null //);// 构造printHello(String whoName)操作信息ModelMBeanOperationInfo print2Info;MBeanParameterInfo[] param2 = new MBeanParameterInfo[1];param2[0] = new MBeanParameterInfo("whoName", STRING_CLASS, "say hello to who");print2Info = new ModelMBeanOperationInfo(//"printHello", //null,//param2,//"void", //MBeanOperationInfo.INFO, //null//);////                        最后总合                                    ////// create ModelMBeanInfoModelMBeanInfo mbeanInfo = new ModelMBeanInfoSupport(//RequiredModelMBean.class.getName(), // MBean类null, // 描述文字new ModelMBeanAttributeInfo[] { // 所有的属性信息(数组)nameAttrInfo },//只有一个属性null, // 所有的构造函数信息new ModelMBeanOperationInfo[] { // 所有的操作信息(数组)getName,setName,print1Info,print2Info },//null, // 所有的通知信息(本例无)null//MBean描述);return mbeanInfo;}
}

这里着重说明下ModelMBeanInfo接口
编写Model MBean的最大挑战是告诉Model MBean对象托管资源的那些熟悉和方法可以暴露给代理。ModelMBeanInfo对象描述了将会暴露给代理的构造函数、属性、操作甚至是监听器。
创建了ModelMBeanInfo对象后,需要将其与ModelMBean对象关联。目前有两种方式可以做到这一点:

  • 传入ModelMBeanInfo对象给RequiredModelMBean对象的构造函数。
  • 调用RequiredModelMBean对象的setModelMBeanInfo方法。

创建了ModelMBean对象后(RequiredModelMBean implements ModelMBean),需要调用ModelMBean接口的setManagedResource()方法将其与托管资源关联,该方法如下:

public void setManagedResource(Object managedResource, String managedResourceType) ;

managedResourceType的值可以为ObjectReference, Handle, IOR, EJBHandle或RMIReference,但当前只支持ObjectReference.

在注册时没有什么特别之处,只是需要注意下通过工具类获得MBean即可

package com.test.jmx.modelBean;import com.sun.jdmk.comm.HtmlAdaptorServer;import javax.management.*;
import javax.management.modelmbean.RequiredModelMBean;
import java.lang.management.ManagementFactory;public class HelloAgent {public static void main(String[] args) throws MalformedObjectNameException, NotCompliantMBeanException, InstanceAlreadyExistsException, MBeanRegistrationException {MBeanServer server = ManagementFactory.getPlatformMBeanServer();ObjectName helloName = new ObjectName("MyMBean:name=HelloWorld");//Hello hello = new Hello();RequiredModelMBean hello = ModelMBeanUtils.createModelerMBean();server.registerMBean(hello, helloName);ObjectName adapterName = new ObjectName("MyMBean:name=htmladapter,port=8082");HtmlAdaptorServer adapter = new HtmlAdaptorServer();server.registerMBean(adapter, adapterName);adapter.start();}
}

运行结果:略。

Model MBean可以动态配置。试想一下这个应用场景:由于安全或其他原因,系统要把某个MBean公开的可管理方法隐藏起来。这时,如果你是用标准MBean,这需要修改接口类,然后重新编译发布;如果用 Apache commons-modeler(如果不想总要维护MBean这个借口,那么可以使用Apache的commons-modeler来辅助开发MBean,所有的MBean都装配在XML文件中)来写的模型MBean,则只需要修改XML文件就行了,不需要重新编译发布(可能要重启一下系统)。这就是Model Mbean 优势之所在了。


参考资料

  1. JMX整理
  2. JMX简介
  3. http://blog.csdn.net/DryKillLogic/article/category/762777
  4. 用Apache的commons-modeler来辅助开发JMX

欢迎跳转到本文的原文链接:https://honeypps.com/java/jmx-quick-start-3-model-mbean/


欢迎支持笔者新作:《深入理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客。


从零开始玩转JMX(三)——Model MBean相关推荐

  1. 从零开始玩转JMX(四)——Apache Commons Modeler Dynamic MBean

    欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...

  2. 从零开始玩转JMX(一)——简介和Standard MBean

    JMX的全称为Java Management Extensions. 顾名思义,是管理Java的一种扩展.这种机制可以方便的管理.监控正在运行中的Java程序.常用于管理线程,内存,日志Level,服 ...

  3. 从零开始玩转JMX(二)——Condition

    欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. 欢迎跳转到本文的原文链接:https: ...

  4. 从零开始玩域名!窥探互联网财富秘密!

    卖域名都能赚到一百亿!福建石狮蔡文胜的传奇人生,巧了,我老乡! 卖域名都能实现财富自由,什么学历?初中学历,什么家庭? 草根纯逆袭!(图) 域名嘛,就是咱们平时输入浏览器的那一串网址(比如www.ba ...

  5. 微信小程序从零开始开发步骤(三)底部导航栏

    上一章节,我们分享了如何创建一个新的页面和设置页面的标题,这一章我们来聊聊底部导航栏是如何实现的.即点击底部的导航,会实现不同对应页面之间的切换. 我们先来看个我们要实现的底部导航栏的效果图:(三个导 ...

  6. SQL Server调优系列玩转篇三(利用索引提示(Hint)引导语句最大优化运行)

    SQL Server调优系列玩转篇三(利用索引提示(Hint)引导语句最大优化运行) 原文:SQL Server调优系列玩转篇三(利用索引提示(Hint)引导语句最大优化运行) 前言 本篇继续玩转模块 ...

  7. 好久没玩laravel了,5.6玩下(三)

    好久没玩laravel了,5.6玩下(三) 好了,基础的测试通了,咱们开始增删改了 思路整理 先创建项目功能控制器 然后设置路由访问规则 然后开发项目的增删改功能 1 先创建项目的控制器 php ar ...

  8. 企业玩TikTok的三种方式

    企业玩TikTok的三种方式 一.电影教育性15秒视频 TikTok与YouTube不一样,在YouTube上,冗长的视频已成为常态.取而代之的是,TikTok视频的建议长度通常为15秒,即15秒宝贵 ...

  9. linux怎么显示第三个数据,从零开始的linux 第三章

    从零开始的linux 第三章 同学们~起床咯~~(小编拿着喇叭在宿舍楼下喊道) 美好的一天从...从赞小编的博客开始~~ (↓看见小编的同学们) 什么!?你们对着可爱的小编说什么!?再说一遍!!? 同 ...

最新文章

  1. robotframework接口测试(二)—post request
  2. F5配置irule,使其系统在X个时间段提供服务,其余时间显示维护页面
  3. 2013年7月31日
  4. 在同一台电脑上同时使用IE6和IE7
  5. django html文本编辑器,django xadmin 集成DjangoUeditor富文本编辑器
  6. SpringMVC访问静态页面
  7. 苹果公司的新的编程语言 Swift 高级语言()两--基本数据类型
  8. Tcp与Ip协议的客户端和服务器编程
  9. 创建动态链接库时设置导出函数的方法
  10. 【API进阶之路】用API打造一条自动化内容生产流水线
  11. js html模板生成图片不显示,网页中图片不显示问题
  12. Linux下安装Nginx详细图解教程
  13. php列表排布,php全排列递归算法代码
  14. ubuntu下的libfetion飞信
  15. Python+OpenCv实现摄像头人脸识别
  16. 宏文件下载_技能 | WPS如何启用宏功能,VBA组件安装
  17. php根据经纬度获取地理位置
  18. 汇佳学校|应博丞:不及格“逆袭”全科满分,粉丝科普博主唤醒想象力
  19. 游戏后台杂谈:后台的语言、系统与构架
  20. html表格边框美化,CSS美化表格边框汇总与效果

热门文章

  1. linux下开发python爬虫_linux入门教程—开发常用命令
  2. emacs python plugin_Windows上配置Emacs来开发Python及用Python扩展Emacs
  3. Altium Desiger18 打印 丝印简单的方法
  4. ASPxGridView EditFormLayout修改 TextBox文本长度
  5. 从MySQL随机选取数据
  6. 窄带物联网有望结束技术应用“碎片化”
  7. Socket-Client通信
  8. CodeForces - 160D Edges in MST(思维+tarjan/树链剖分+线段树)
  9. POJ - 3422 Kaka's Matrix Travels(网络流-最大费用最大流+拆点法)
  10. PAT (Basic Level) 1055 集体照(模拟,好题)