这些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对话框中。