从零开始玩转JMX(三)——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 ModelMBeanInfo
ModelMBeanInfo 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 优势之所在了。
参考资料
从零开始玩转JMX(三)——Model MBean的更多相关文章
- 从零开始玩转JMX(四)——Apache Commons Modeler & Dynamic MBean
Apache Commons Modeler 前面的Model MBean的创建方式看上去特别复杂,一个简单功能的类ModelMBeanUtils 写了很多代码,那有木有简单点的方式呢,答案是肯定的, ...
- 从零开始玩转JMX(一)——简介和Standard MBean
JMX的全称为Java Management Extensions. 顾名思义,是管理Java的一种扩展.这种机制可以方便的管理.监控正在运行中的Java程序.常用于管理线程,内存,日志Level,服 ...
- 从零开始玩转JMX(二)——Condition
Notification 一个MBean提供的管理接口允许代理对其管理资源进行控制和配置.然而,对管理复杂的分布式系统来说,这些接口知识提供了一部分功能.通常,管理应用程序需要对状态变化或者当特别情况 ...
- 从零开始学Xamarin.Forms(三) Android 制作启动画面
原文:从零开始学Xamarin.Forms(三) Android 制作启动画面 Xamarin.Forms 在启动的时候相当慢,必须添加一个启动界面,步骤如下: 1.将启动画面的图片命名为:s ...
- 微信小程序从零开始开发步骤(三)底部导航栏
上一章节,我们分享了如何创建一个新的页面和设置页面的标题,这一章我们来聊聊底部导航栏是如何实现的.即点击底部的导航,会实现不同对应页面之间的切换. 我们先来看个我们要实现的底部导航栏的效果图:(三个导 ...
- 从零开始使用git第三篇:git撤销操作、分支操作和常见冲突
从零开始使用git 第三篇:git撤销操作.分支操作和常见冲突 第一篇:从零开始使用git第一篇:下载安装配置 第二篇:从零开始使用git第二篇:git实践操作 第三篇:从零开始使用git第三篇:gi ...
- 从零开始学习MXnet(三)之Model和Module
在我们在MXnet中定义好symbol.写好dataiter并且准备好data之后,就可以开开心的去训练了.一般训练一个网络有两种常用的策略,基于model的和基于module的.今天,我想谈一谈他们 ...
- Excel应该这么玩——5、三种数据:Excel也是系统
Excel最常用的功能就是记录数据,把数据按照行列记录下来.这部分数据是源数据,是业务活动中最原始的流水账,作为后续操作的依据.为了从源数据中得出一定的结论,需要对源数据进行分析得出报表数据. ...
- SQL Server调优系列玩转篇三(利用索引提示(Hint)引导语句最大优化运行)
前言 本篇继续玩转模块的内容,关于索引在SQL Server的位置无须多言,本篇将分析如何利用Hint引导语句充分利用索引进行运行,同样,还是希望扎实掌握前面一系列的内容,才进入本模块的内容分析. 闲 ...
随机推荐
- R中利用SQL语言读取数据框(sqldf库的使用)
熟悉MySQL的朋友可以使用sqldf来操作数据框 # 引入sqldf库(sqldf) library(sqldf) # 释放RMySQL库的加载(针对sqldf报错) #detach("p ...
- C#批量入库
public static void BulkCopyToDB(DataTable dt, string conn, string tableName, out string msg) { msg = ...
- Xcode升级了6.3 出现的警告:Auto property synthesis will not synthesize property
1. Auto property synthesis will not synthesize property 'title'; it will be implemented by its supe ...
- netty/example/src/main/java/io/netty/example/http/snoop/
netty/example/src/main/java/io/netty/example/http/snoop at 4.1 · netty/netty https://github.com/nett ...
- ROS 笔记
ros的编程范式 - ros认为,linux平台下,机器人的软件由一个个小程序组成,这些小程序称为node,每个小程序负责一部分功能 - ros实现的框架就是,小程序的并发执行+相互通信,程序(进程) ...
- nsq里面WaitGroups两种实用的用法
看过好几遍了,觉得挺实用的,记录备忘一下. 1.开启很多个 goroutine 之后,等待执行完毕 type WaitGroupWrapper struct { sync.WaitGroup } fu ...
- js-jquery-001-条形码概述
一.概述 百度百科 条形码(barcode)是将宽度不等的多个黑条和空白,按照一定的编码规则排列,用以表达一组信息的图形标识符. 通用商品条形码一般由前缀部分.制造厂商代码.商品代码和校验码组成.商品 ...
- Spark2.x AFTSurvivalRegression算法
Spark2.0的机器学习算法比之前的改变最大的是2.0基本采用了dataframe来实现的,但之前的都是用的RDD,看官网说貌似在3.0的时候RDD就不用了!还有一个就是hiveContext和sq ...
- IntelliJ IDEA的几个常用快捷键
一.将IntelliJ IDEA的快捷键设置为Eclipse环境的快捷键 如果之前长期使用Eclipse作为开发工具的程序员在刚开始接触IDEA的时候肯定会很不习惯,所以如果你没有太多时间去研究的话可 ...
- WSDL(WebService描述语言)文件介绍
一.WSDL 1.WSDL 文档的组成部分 <portType>:web service 执行的操作 <message>:web service 使用的消息 <types ...