JMX(Java Management Extensions,即Java管理扩展)是一个为应用程序、设备、系统等植入管理功能的框架。
JMX可以跨越一系列异构操作系统平台、系统体系结构和网络传输协议,灵活的开发无缝集成的系统、网络和服务管理应用。
JMX是一份规范,就好像JDBC,SUN依据这个规范在JDK提供了JMX接口。
而根据这个接口的实现则有很多种,比如Weblogic的JMX实现、MX4J、JBoss的JMX实现。
在SUN自己也实现了一份,不过在JDK1.4之前,这件JMX实现是可选的,你得去它的网站上下载。
JDK5.0则内嵌了进来,安装JDK5.0就可以开发基于JMX的代码了。
MBean 即 managed beans 被管理的Beans
JMX共有四种MBean:
标准MBeans(Standard MBeans)设计和实现是最简单的,这类MBean使用自己的方法名作为管理接口;
动态MBeans(Dynamic MBeans)必须实现一个指定的接口,由于动态MBeans在运行期间暴露它们的管理接口,因此更为灵活;
开放MBeans(Open MBeans)属于动态MBeans,这类MBean依靠基础数据类型来实现通用管理,并为友情用户进行自我声明;
模型MBeans(Model MBeans)同样也是动态MBeans,这类MBeans是完全可配置的,在运行期间进行自我声明;它们为资源动态工具提供一个一般性的,有默认行为的MBeans类。
通常一个MBean需要定义一个接口,以MBean结尾
public interface EchoMBean { public void print(String name); }
上面的接口定义了一个echo方法 参数为String类型
public class Echo implements EchoMBean { @Override public void print(String name) { System.out.println("Hello " + name); } }
Echo简单实现了EchoMBean接口 打印Hello +name
按照JMX的定义 我们现在只是实现了这个被管理的对象 而并没有管理起来
import java.lang.management.ManagementFactory; import javax.management.MBeanServer; import javax.management.ObjectName; public class Example { public static void main(String[] args) throws Exception { MBeanServer server = ManagementFactory.getPlatformMBeanServer(); ObjectName name = new ObjectName("mbean:type=Echo"); Echo echo = new Echo(); server.registerMBean(echo, name); server.invoke(name, "print", new Object[] { "darion.yaphet" }, new String[] { "java.lang.String" }); Thread.sleep(1000 * 60); } }
各个步骤主要用来:
ManagementFactory申请一个MBeanServer
给Echo对象被管理起来需要给他起一个名字,作为对象标识符
这里也就是ObjectName , 用包名::type=类名的形式表示
通过server.registerMBean方法注册被管理对象
server.invoke方法调用被注册对象的指定方法 并传入所需参数和参数类型
通过jconsole我们可以调用echo对象上的print方法 并设置指定参数
这种方法可以用来动态设置参数 而不用停止进程
JMX中的订阅模型类似于观察者模式 当有通知到达的时候 通过调用观察者逐一执行
这句话说得不是很明白 举例说明下:
首先定义一个MBean接口:
public interface ServerConfigureMBean { public void setPort(int port); public int getPort(); public void setHost(String host); public String getHost(); }
ServerConfigure雷继承了NotificationBroadcasterSupport 实现广播服务
public class ServerConfigure extends NotificationBroadcasterSupport implements ServerConfigureMBean { private AtomicLong sequenceNumber = new AtomicLong(1); private int port; private String host; public void setPort(int port) { int oldPort = this.port; this.port = port; AttributeChangeNotification notification = new AttributeChangeNotification( this, sequenceNumber.getAndIncrement(), System.currentTimeMillis(), AttributeChangeNotification.ATTRIBUTE_CHANGE, "Server Port Change", "java.lang.Integer", oldPort + "", this.port + ""); super.sendNotification(notification); } public int getPort() { return port; } public void setHost(String host) { String oldHost = this.host; this.host = host; AttributeChangeNotification notification = new AttributeChangeNotification( this, sequenceNumber.getAndIncrement(), System.currentTimeMillis(), AttributeChangeNotification.ATTRIBUTE_CHANGE, "Server Host Change", "java.lang.String", oldHost, this.host); super.sendNotification(notification); } public String getHost() { return host; } }
AttributeChangeNotification -- 属性变更通知
参数为:事件源、通知序号、通知发布时间戳、通知message、属性名、属性类型、修改之前的值以及修改之后的值
NotificationBroadcasterSupport用于提供广播机制、调用sendNotification方法发送广播
import javax.management.Notification; import javax.management.NotificationListener; public class ServerConfigureNotificationListener implements NotificationListener { public void handleNotification(Notification notification, Object handback) { log("SequenceNumber:" + notification.getSequenceNumber()); log("Type:" + notification.getType()); log("Message:" + notification.getMessage()); log("Source:" + notification.getSource()); log("TimeStamp:" + notification.getTimeStamp()); } private void log(String message) { System.out.println(message); } }
简单测试一下 使用这种方法可以动态修改一些配置参数 !~
import java.lang.management.ManagementFactory; import javax.management.MBeanServer; import javax.management.ObjectName; public class ServerStartup { public static void main(String[] args) throws Exception { MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); ObjectName name = new ObjectName( "org.darion.mbean:type=ServerConfigure"); ServerConfigure mbean = new ServerConfigure(); mbs.registerMBean(mbean, name); ServerConfigureNotificationListener listener = new ServerConfigureNotificationListener(); mbs.addNotificationListener(name, listener, null, null); Thread.sleep(1000*120); } }
参考文献:
http://baike.baidu.com/link?url=nnQdka_1amvgJiQgaCx1XLfXUv_mChQbkGLMREF8NxAeDp9rCAlWAo5tuVEWgUHg
http://blog.csdn.net/qiao000_000/article/category/763467