介绍
Java Management Extensions(Java管理扩展)。通俗的讲,通过JMX可以对Java对象进行管理和检测。
JMX是Java Platform Standard Edition的一部分。
JMX三层体系结构
Instrumentation Level(仪表层)
其实我觉得叫MBean层更合适些。因为这层面向的是JVM中需要管理的MBean资源对象。
Agent Level(代理层)
之所以是代理层,是因为所有的要管理的MBean对象都要注册到MBean Server中。通过这个代理对象来对MBean做操作。
Distributed Services Level(分布式服务层)
如下图,可以看到,MBean和MBean Server都是在JVM中的,分布式服务层中外部应用通过Connector和Protocol Adaptors访问代理层中的MBean Server。
手划的类关系图
Instrumentation Level的组件
Managed Beans (MBeans)
受管理的Bean文件。
Notification Model
JMX规范定义一个基于Java事件Notification Model。notification对象以及broadcaster和listener接口。
MBean Metadata Classes
Metadata定义了MBean的attributes, operations, notifications 和constructors。
Managed Beans (MBeans)
MBean是一个受管理的具体Java类。
Standard MBean
标准的MBean。
一个叫“XXXMBean”的接口。
这个接口定义的方法暴露给代理层,用于访问下面的具体实现类。
一个实现“XXXMBean”接口的类。
Demo:
MBean Interface:
package com.adeng.demo.jmx.mbeans.standard;
public interface HelloMBean {
public void sayHello();
public int add(int x, int y);
public String getName();
public int getCacheSize();
public void setCacheSize(int size);
}
MBean Interface的实现类:
package com.adeng.demo.jmx.mbeans.standard;
public class Hello implements HelloMBean{
private String name = "HelloName";
private int cacheSize = 100;
public void sayHello() {
System.out.println("Hello, world!");
}
public int add(int x, int y) {
return x + y;
}
public String getName() {
return name;
}
public int getCacheSize() {
return cacheSize;
}
public void setCacheSize(int size) {
cacheSize = size;
}
}
运行代码:
package com.adeng.demo.jmx.mbeans.standard;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
public class Main {
public static void main(String[] args) throws Exception {
/* 获取平台的MBeanServer对象,如果没有会调用MBeanServerFactory.createMBeanServer()创建 */
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
/* ObjectName对象是用来标识MBean。
* 使用字符串[domainName]:property=value[,property=value]*
*/
ObjectName name = new ObjectName("com.adeng.demo.jmx.mbeans.standard:type=Hello");
Hello hello = new Hello();
mBeanServer.registerMBean(hello, name);
System.out.println("一直等待......");
Thread.sleep(Long.MAX_VALUE);
}
}
之后,就可以通过Jconsole连接,操作Hello对象了。Hello对象上的Name属性和cacheSize属性都是可以直接修改的。
MXBeans
MXBean是一种仅引用预定义数据类型的MBean类型。
MXBean与标准MBean一样,需要定义一个“XXXMXBean”的接口。也可以通过注解@MXBean(true)
标识接口。
在MXBean接口中引用的类型(如java.lang.management.MemoryUsage java.lang.management.MemoryMXBean)被映射到标准的一组类型中,即所谓的Open在包javax.management.openmbean中定义的类型。确切的映射规则出现在MXBean规范中。但是,一般的原则是对于简单类型(如int或String)保持不变,而将复杂类型(如MemoryUsage)映射到标准类型CompositeDataSupport。
Demo:
MXBean interface
package com.adeng.jmx.example.mbeans.mxbean;
/*
或者使用 @MXBean(true),接口名后缀就可以不为“MXBean”
*/
public interface QueueSamplerMXBean {
/* 这里的返回类型被映射成 javax.management.openmbean.CompositeData */
public QueueSample getQueueSample();
public void clearQueue();
}
MXBean interface实现类
package com.adeng.jmx.example.mbeans.mxbean;
import java.util.Date;
import java.util.Queue;
public class QueueSampler implements QueueSamplerMXBean {
private Queue<String> queue;
public QueueSampler(Queue<String> queue) {
this.queue = queue;
}
public QueueSample getQueueSample() {
synchronized (queue) {
return new QueueSample(new Date(), queue.size(), queue.peek());
}
}
public void clearQueue() {
synchronized (queue) {
queue.clear();
}
}
}
package com.adeng.jmx.example.mbeans.mxbean;
import java.beans.ConstructorProperties;
import java.util.Date;
public class QueueSample {
private final Date date;
private final int size;
private final String head;
@ConstructorProperties({
"date", "size", "head"})
public QueueSample(Date date, int size, String head) {
this.date = date;
this.size = size;
this.head = head;
}
public Date getDate() {
return date;
}
public int getSize() {
return size;
}
public String getHead() {
return head;
}
}
Main:
package com.adeng.jmx.example.mbeans.mxbean;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
public class MXBeanMai