这些Java教程是针对JDK 8编写的。本页面中描述的示例和实践不利用后续版本中引入的改进,并且可能使用已不再可用的技术。
有关Java SE 9及后续版本中更新的语言特性的摘要,请参阅Java语言更改。
有关所有JDK版本的新功能、增强功能以及已删除或弃用选项的信息,请参阅JDK发行说明。
这一节介绍了一个简单、标准的MBean的示例。
标准的MBean是通过编写一个名为SomethingMBean的Java接口和一个名为Something的Java类来定义的,该类实现了该接口。接口中的每个方法定义了MBean中的一个属性或操作。默认情况下,每个方法定义一个操作。属性和操作是遵循某些设计模式的方法。标准的MBean由MBean接口和类组成。MBean接口列出了所有公开的属性和操作的方法。类实现这个接口并提供了受监控资源的功能。
下面的章节将介绍一个标准MBean的示例以及一个管理该MBean的简单JMX技术启用的代理(JMX代理)。
一个基本MBean接口的示例,HelloMBean,如下所示:
package com.example;
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接口的名称与实现它的Java类的名称相同,后缀MBean被添加。在本例中,接口被称为HelloMBean。实现该接口的Hello类将在下一节中进行描述。
根据JMX规范,MBean接口由可读取和可能可写的具有名称和类型的属性组成,以及可以被MBean管理的应用程序调用的具有名称和类型的操作。 HelloMBean接口声明了两个操作:Java方法add()和sayHello()。
HelloMBean声明了两个属性:Name是一个只读字符串,CacheSize是一个可读可写的整数。声明了getter和setter方法,以允许受管理的应用程序访问和可能更改属性值。根据JMX规范的定义,getter是任何不返回void并且以get开头的公共方法。getter使管理者能够读取属性的值,其类型与返回的对象的类型相同。setter是任何接受单个参数并且以set开头的公共方法。setter使管理者能够将新值写入属性,其类型与参数的类型相同。
这些操作和属性的实现在下一节中展示。
下面的Java类Hello实现了HelloMBean MBean接口:
package com.example;
public class Hello ...
implements HelloMBean {
public void sayHello() {
System.out.println("你好,世界");
}
public int add(int x, int y) {
return x + y;
}
public String getName() {
return this.name;
}
public int getCacheSize() {
return this.cacheSize;
}
public synchronized void setCacheSize(int size) {
...
this.cacheSize = size;
System.out.println("缓存大小现在为" + this.cacheSize);
}
...
private final String name = "Reginald";
private int cacheSize = DEFAULT_CACHE_SIZE;
private static final int
DEFAULT_CACHE_SIZE = 200;
}
直接的Hello类提供了HelloMBean声明的操作和属性的定义。 sayHello()和add()操作非常简单,但实际操作可以根据需要简单或复杂。
定义了获取Name属性以及获取和设置CacheSize属性的方法。在此示例中,Name属性值永远不会更改。但在实际情况中,该属性可能会随着所管理资源的运行而更改。例如,该属性可能表示运行时间或内存使用情况等统计信息。在此示例中,属性只是名称Reginald。
调用setCacheSize方法可以更改CacheSize属性,将其从声明的默认值200更改为其他值。在实际情况中,更改CacheSize属性可能需要执行其他操作,例如丢弃条目或分配新条目。此示例仅打印消息以确认缓存大小已更改。但是,可以定义更复杂的操作,而不仅仅是简单的调用println()。
通过定义Hello MBean及其接口,可以使用它们来管理所代表的资源,如下一节所示。
一旦资源被MBean进行了仪器化,该资源的管理就由JMX代理执行。
JMX代理的核心组件是MBean服务器。 MBean服务器是一个受管理的对象服务器,其中注册了MBean。 JMX代理还包括一组用于管理MBean的服务。有关MBean服务器实现的详细信息,请参阅MBeanServer接口的API文档。
接下来的Main类代表了一个基本的JMX代理:
package com.example;
import java.lang.management.*;
import javax.management.*;
public class Main {
public static void main(String[] args)
throws Exception {
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName name = new ObjectName("com.example:type=Hello");
Hello mbean = new Hello();
mbs.registerMBean(mbean, name);
...
System.out.println("等待中...");
Thread.sleep(Long.MAX_VALUE);
}
}
JMX代理Main首先通过调用java.lang.management.ManagementFactory类的getPlatformMBeanServer()方法,获取由平台创建和初始化的MBean服务器。如果平台尚未创建MBean服务器,则getPlatformMBeanServer()方法会自动调用JMX方法MBeanServerFactory.createMBeanServer()来创建MBean服务器。由Main获取的MBeanServer实例被命名为mbs。
接下来,Main为将创建的MBean实例定义了一个对象名称。每个JMX MBean都必须有一个对象名称。对象名称是JMX类ObjectName的一个实例,必须符合JMX规范定义的语法。换句话说,对象名称必须包含一个域和一组键属性。在Main定义的对象名称中,域是com.example(示例MBean所在的包)。此外,键属性声明此对象为Hello类型。
创建一个名为mbean的Hello对象实例。然后,将命名为mbean的Hello对象注册为MBean,通过将对象和对象名称传递给JMX方法MBeanServer.registerMBean()。
在MBean服务器中注册了Hello MBean之后,Main只需等待对Hello执行管理操作。在此示例中,这些管理操作包括调用sayHello()和add()方法,以及获取和设置属性值。
在检查了示例类之后,您现在可以运行示例。在这个示例中,我们使用JConsole与MBean进行交互。
要运行示例,请按照以下步骤进行:
jmx_examples.zip保存到您的工作目录work_dir中。unzip jmx_examples.zip
work_dir目录中编译示例Java类。
javac com/example/*.java
Main应用程序。
java com.example.Main
如果您使用的是早于版本6的JDK版本,您需要使用以下指定选项启动Main应用程序,以便将应用程序暴露给监控和管理。
java -Dcom.sun.management.jmxremote example.Main
显示了Main正在等待某些事情发生的确认信息。
jconsole
显示新连接对话框,呈现可连接的运行中JMX代理的列表。
com.example.Main并点击连接。
显示了您平台当前活动的摘要。
此面板显示当前在MBean服务器中注册的所有MBean。
com.example节点。
您可以看到由Main创建和注册的示例MBeanHello。如果您点击Hello,您将在MBean树中看到其关联的Attributes和Operations节点。
Hello MBean的Attributes节点。
显示了由Hello类定义的MBean属性。
CacheSize属性的值更改为150。
在您启动Main的终端窗口中,将生成此属性更改的确认信息。
Hello MBean的Operations节点。
可见Hello MBean声明的两个操作sayHello()和add()。
sayHello按钮来调用sayHello()操作。
JConsole对话框将通知您方法已成功调用。在运行Main的终端窗口中生成消息"hello, world"。
add()操作提供两个整数并点击add按钮。
答案将显示在JConsole对话框中。