blob: 7e6eb13970ddb0fd8351ceb23b5455b76f071a15 [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!--
Copyright (c) 2009, 2010, 2011, Oracle and/or its affiliates. All rights reserved.
-->
<html>
<head>
<title>在 NetBeans IDE 中将 Java 管理扩展 (JMX) 分析添加到 Java 应用程序中</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" >
<meta name="description" content="Anagram Game JMX instrumentation tutorial for the NetBeans JMX Wizard module">
<link rel="stylesheet" href="../../../netbeans.css">
<meta name="TOPIC" content="ADVANCED">
<meta name="TYPE" content="ARTICLE">
<meta name="AUDIENCE" content="NBUSER">
<meta name="author" content="Jean-Francois DENISE">
<meta name="author" content="Joel FERAUD">
<meta name="KEYWORDS" content="NETBEANS, TUTORIAL, GUIDE, USER, DOCUMENTATION, JMX">
<meta name="description" content="An tutorial on how to add JMX management to an application in NetBeans IDE"/>
</head>
<body>
<h1>将 Java 管理扩展 (JMX) 分析添加到 Java 应用程序中</h1>
<center><b>预计时间:60 分钟</b></center>
<p>NetBeans JMX 向导模块将 JMX 技术集成到 NetBeans IDE 中的工作流。此模块允许您快速开发管理应用程序,向现有应用程序添加管理,开发管理器应用程序,以及监视虚拟机的状态。</p>
<p>本教程将向您演示如何将管理添加到现有应用程序(NetBeans 样例 Anagrams Game 应用程序)。首先,您将创建一个不可管理的 Anagram Java 项目。然后,使用 JMX 向导生成 90% 的管理。接下来,实现特定于应用程序的管理行为。最后,结合使用“运行/调试”项目和 JConsole 以可视化 Anagram MBean。 </p>
<h3>教程练习</h3>
<img alt="此页上的内容适用于 NetBeans IDE 7.2、7.3、7.4 和 8.0" class="stamp" src="../../../images_www/articles/73/netbeans-stamp-80-74-73.png" title="此页上的内容适用于 NetBeans IDE 7.2、7.3、7.4 和 8.0">
<ul>
<li><a href="#Exercise_1">练习 1:创建 NetBeans 样例 Anagram Game 项目</a></li>
<li><a href="#Exercise_2">练习 2:创建 AnagramsStats JMX 标准 MBean 及其管理界面</a></li>
<li><a href="#Exercise_3">练习 3:将属性、操作和通知添加到 AnagramsStats JMX 标准 MBean 中</a></li>
<li><a href="#Exercise_4">练习 4:将实现代码添加到 AnagramsStats JMX 标准 MBean 中</a></li>
<li><a href="#Exercise_5">练习 5:将管理和应用程序连接在一起</a></li>
<li><a href="#Exercise_6">练习 6:使用 JConsole 运行 Anagram Game</a></li>
</ul>
<h3>先决条件</h3>
<p>本教程假定您具备以下技术的一些基本知识或编程经验。 </p>
<ul>
<li>JMX 技术:<a href="http://download.oracle.com/javase/6/docs/technotes/guides/jmx/index.html">JMX 联机文档</a></li>
<li>Java 技术:<a href="http://www.oracle.com/technetwork/java/javase/tech/index.html">Java SE 技术概览</a></li>
<li>NetBeans IDE</li>
</ul>
<p>您还将受益于在 <a href="http://download.oracle.com/javase/6/docs/technotes/guides/management/index.html">Java 平台的监视和管理</a>方面的一些知识</p>
<h3>本教程所需要的软件</h3>
<p>在学习本教程之前,您需要在计算机上安装以下软件:</p>
<table>
<tbody>
<tr>
<th class="tblheader" scope="col">软件或资源</th>
<th class="tblheader" scope="col">要求的版本</th>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/downloads/index.html">NetBeans IDE</a></td>
<td class="tbltd1">7.2、7.3、7.4、8.0、Java 版本</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">Java 开发工具包 (JDK)</a></td>
<td class="tbltd1">版本 7 或 8</td>
</tr>
<tr>
<td class="tbltd1">JMX 插件</td>
<td class="tbltd1">可从 NetBeans 更新中心获得</td>
</tr>
<tr>
<td class="tbltd1">JConsole 插件</td>
<td class="tbltd1">可从 NetBeans 更新中心获得</td>
</tr>
</tbody>
</table>
<p>要安装 <strong>JMX</strong><strong>JConsole</strong> 插件,请选择“工具”>“插件”,然后从 NetBeans 更新中心下载模块。</p>
<h3>资源</h3>
<ul>
<li>NetBeans 帮助目录(“帮助”>“帮助目录”> "JMX")。也可从向导中获得此帮助。</li>
</ul>
<h2><a name="Exercise_1"></a>练习 1:创建 NetBeans 样例 Anagram Game 项目</h2>
<p>本练习的目标是创建可运行的 Java 项目。Anagram Game 是一个 Swing 应用程序,向用户显示混乱词并等待用户解决 Anagram。 </p>
<ol>
<li>选择 "File"(文件)> "New Project"(新建项目)(Ctrl-Shift-N 组合键)。</li>
<li>选择“样例”> "Java" 类别。</li>
<li>选择 Anagram Game 项目。单击“下一步”。</li>
<li>在“项目名称和位置”面板中,设置项目位置,或者保留默认值(如果该值适合您)。选中“设置为主项目”复选框(如果未选中),因为它将使后续操作更加简便。单击“完成”。
<p>单击“完成”后,IDE 将创建 Anagram Game 项目,并在“项目”窗口中显示该项目。</p>
</li>
<li>右键单击 "AnagramGame" 项目,然后选择“属性”。</li>
<li>选择“源”类别并确认源代码/二进制格式设置为 "JDK 7" 或 "JDK 8"。单击“确定”。
<p class="notes"><strong>注:</strong>要选择 JDK 7 或 JDK 8,AnagramGame 项目的 Java 平台也必须分别至少为 JDK 7 或 JDK 8。可在“属性”窗口的“库”类别中更改 AnagramGame 的 Java 平台。</li>
<li>右键单击 "Anagram Game" 项目节点并选择“运行”。</li>
</ol>
<p>选择“运行”后,IDE 将构建并启动 Anagram Game 应用程序。</p>
<h2><a name="Exercise_2"></a>练习 2:创建 AnagramsStats JMX 标准 MBean 及其管理界面</h2>
<p>本练习的目标是创建由实现类和管理界面组成的框架 JMX 标准 MBean。</p>
<p>请执行以下步骤以创建 JMX 标准 MBean。</p>
<ol>
<li>确认 "Anagram Game" 项目设置为主项目。 </li>
<li>选择 "File"(文件)> "New File"(新建文件)(Ctrl-N 组合键)。</li>
<li>从 "JMX" 类别中选择 "Standard MBean"(标准 MBean)。单击 "Next"(下一步)。<br /> <img alt="&amp;quot;New File&amp;quot;(新建文件)向导中的 &amp;quot;Standard MBean&amp;quot;(标准 MBean)文件类型的屏幕快照" class="margin-around b-all" src="../../../images_www/articles/74/java/jmx/jmx-newfile.png" title="&amp;quot;New File&amp;quot;(新建文件)向导中的 &amp;quot;Standard MBean&amp;quot;(标准 MBean)文件类型" /></li>
<li>在 "Name and Location"(名称和位置)面板中输入以下信息:
<ul>
<li>类名:<tt>AnagramsStats</tt></li>
<li>位置:源包(默认值)</li>
<li>包:<tt>com.toy.anagrams.mbeans</tt></li>
<li>描述:<tt>Anagram Game 的监视和管理</tt></li>
</ul>
<br clear="all" /> <img alt="create_mbean2:创建新的标准 MBean,步骤 2" class="margin-around b-all" src="../../../images_www/articles/74/java/jmx/jmx-newmbean.png" />
</li>
<li>单击 "Finish"(完成)。</li>
</ol>
<p>单击 "Finish"(完成)后,将在 AnagramGame 项目的 <tt>com.toy.anagrams.mbeans</tt> 包中生成 <tt>AnagramsStats</tt> MBean 类和 <tt>AnagramsStatsMBean</tt> MBean 接口。这些现在是几个空框架,在下一练习中将进行填充。</p>
<h2><a name="Exercise_3"></a>练习 3:将属性、操作和通知添加到 AnagramsStats JMX 标准 MBean 中</h2>
<p>本练习的目标是填充生成的 MBean 框架,以使其监视用户解决新 Anagram 所用的时间,并在 Anagram 每次得到解决时发送 JMX 通知。 </p>
<p>MBean 将包含以下内容: </p>
<ul>
<li>两个名为 <tt>LastThinkingTime</tt><tt>NumResolvedAnagrams</tt> 的属性 </li>
<li>一个名为 <tt>resetAll</tt> 的操作。 </li>
<li>一个 <tt>AttributeChangeNotification</tt> 类型的通知。更新 <tt>LastThinkingTime</tt> 时将发出此通知。</li>
</ul>
<p>请执行以下步骤以填充 MBean 框架。</p>
<ol>
<li>在 NetBeans 编辑器中打开 <tt>AnagramsStats.java</tt> MBean 实现文件。</li>
<li>在源代码编辑器中右键单击,然后在弹出菜单中选择 <strong>JMX > Add MBean Attributes</strong>(JMX > 添加 MBean 属性)。 </li>
<li>通过单击 "Add Attribute"(添加属性)按钮并提供以下信息来添加 <tt>LastThinkingTime</tt> 属性。
<ul>
<li>属性名:<tt>LastThinkingTime</tt></li>
<li>类型:int</li>
<li>访问权限:ReadOnly</li>
<li>描述:<tt>解决最后一个 Anagram 的用时</tt></li>
</ul>
<p class="notes"><strong>注:</strong>还不要单击 "OK"(确定)!</p>
</li>
<li>再次单击 "Add Attribute"(添加属性)并添加以下 <tt>NumSolvedAnagrams</tt> 属性。单击 "OK"(确定)。
<ul>
<li>属性名:<tt>NumSolvedAnagrams</tt></li>
<li>类型:int</li>
<li>访问权限:ReadOnly</li>
<li>描述:<tt>已解决的 Anagram 数量</tt></li>
</ul>
<br /> <img alt="create_mbean7:添加 LastThinkingTime 属性" class="margin-around b-all" src="../../../images_www/articles/74/java/jmx/jmx-addattribute.png" />
<p><tt>AnagramsStats</tt> MBean 类及其接口中生成公开只读的 <tt>LastThinkingTime</tt><tt>NumSolvedAnagrams</tt> 属性所需的代码。</p>
<p>您可以看到私有字段声明和公共 getter 方法。更准确地说,查看成员视图,在生成的节点处您会注意到 <tt>getLastThinkingTime</tt><tt>getNumSolvedAnagrams</tt> 方法在 <tt>AnagramsStats</tt> 类及其 <tt>AnagramsStatsMBean</tt> 接口中都已生成。同时也生成了 <tt>int</tt> 类型的私有字段 <tt>lastThinkingTime</tt><tt>numSolvedAnagrams</tt>,并且这些字段将用于存储实际属性值。</p>
<p>接下来,将另外添加三个属性以跟踪用户所用的最短和最长思考时间以及当前向用户提供的 Anagram。 </p>
</li>
<li>在源代码编辑器中右键单击,然后在弹出菜单中选择 <strong>JMX > Add MBean Attributes</strong>(JMX > 添加 MBean 属性)。</li>
<li>单击 "Add Attribute"(添加属性)按钮并添加以下属性。
<table border="1" cellpadding="1">
<thead>
<tr>
<th>属性名</th>
<th>类型</th>
<th>访问权限</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>MinThinkingTime</td>
<td>int</td>
<td>ReadOnly</td>
<td>解决 Anagram 的最短用时</td>
</tr>
<tr>
<td>MaxThinkingTime</td>
<td>int</td>
<td>ReadOnly</td>
<td>解决 Anagram 的最长用时</td>
</tr>
<tr>
<td>CurrentAnagram</td>
<td>String</td>
<td>ReadOnly</td>
<td>当前要解决的 Anagram</td>
</tr>
</tbody>
</table>
<p>此对话框应与下图类似。</p>
<img alt="另外添加 3 个属性后的 &amp;quot;Add Attribute&amp;quot;(添加属性)对话框的屏幕快照" class="margin-around b-all" src="../../../images_www/articles/74/java/jmx/jmx-addattribute2.png" title="另外添加 3 个属性后的 &amp;quot;Add Attribute&amp;quot;(添加属性)对话框" />
<p class="notes"><strong>注:</strong>请注意,此对话框中列出了您已创建的属性。</p>
</li>
<li>单击 "OK"(确定)保存您所做的更改。</li>
<li>在源代码编辑器中右键单击,然后在弹出菜单中选择 <strong>JMX > Add MBeans Operations</strong>(JMX > 添加 MBean 操作)。</li>
<li>单击 "Add Operation"(添加操作),然后添加 <tt>resetAll()</tt> 操作并指定以下详细信息。单击 "OK"(确定)。
<ul>
<li>操作名:<tt>resetAll</tt></li>
<li>返回类型:<tt>void</tt></li>
<li>参数:(留空)</li>
<li>异常错误:(留空)</li>
<li>描述:<tt>重置 MBean 状态</tt></li>
</ul>
<br /> <img alt="&amp;quot;Add Operation&amp;quot;(添加操作)对话框的屏幕快照" class="margin-around b-all" src="../../../images_www/articles/74/java/jmx/jmx-addoperation.png" title="在 &amp;quot;Add Operation&amp;quot;(添加操作)对话框中添加 resetAll 操作" />
<p>单击 "OK"(确定)后,您可以看到在 <tt>AnagramsStats</tt> MBean 类及其接口中生成了公开 <tt>resetAll</tt> 操作所需的代码。 </p>
</li>
<li>在源代码编辑器中右键单击,然后在弹出菜单中选择 <strong>JMX > Implement NotificationEmitter interface</strong>(JMX > 实现 NotificationEmitter 接口)。</li>
<li>在 "Implement NotificationEmitter interface"(实现 NotificationEmitter 接口)对话框中指定以下详细信息。
<ul>
<li><strong>选择 "Generate Delegation to Broadcaster"(生成到广播器的委托)。</strong>将通过委托到通知广播器来实现 <tt>NotificationEmitter</tt> 接口声明的所有方法。通知广播器将简化 MBean 发送通知的方式。</li>
<li><strong>选择 "Generate Private Seq Number and Accessor"(生成私有序列号和存取方法)。</strong>将生成一些代码以处理必须添加到发送的每个通知的唯一序列号值。</li>
<li><strong>单击 "Add Notification"(添加通知)。</strong>在 "Notifications"(通知)表中指定以下详细信息。
<ul>
<li>通知类:<tt>javax.management.AttributeChangeNotification</tt></li>
<li>通知类型:(自动设置为 <tt>ATTRIBUTE_CHANGE</tt></li>
<li>描述:<tt>已解决 Anagram</tt><br></li>
</ul>
</li>
</ul>
<br /> <img alt="&amp;quot;Implement NotificationEmitter&amp;quot;(实现 NotificationEmitter)对话框的屏幕快照" class="margin-around b-all" src="../../../images_www/articles/74/java/jmx/jmx-changenotification.png" title="在 &amp;quot;Implement NotificationEmitter&amp;quot;(实现 NotificationEmitter)对话框中添加更改通知" />
<p>单击 "OK"(确定)。</p>
<p>您可以看到在 <tt>AnagramsStats</tt> MBean 类中生成了实现 <tt>NotificationEmitter</tt> 接口所需的代码。您可以查看生成的实现如何将通知处理委托到 <tt>NotificationBroadcasterSupport</tt> 类。</p>
</li>
<li>保存所做的更改。</li>
</ol>
<p>在本练习中,您了解了如何使用 JMX 向导模块将属性、操作和发出的通知添加到 MBean 中。现已完成使用所需基础结构填充 MBean 以公开需要的管理信息所需执行的步骤。现在,您需要将内部逻辑添加到 <tt>AnagramsStats</tt> MBean 类实现中,然后在 MBean 与 Anagram Game 应用程序之间构建桥。</p>
<h2><a name="Exercise_4"></a>练习 4:将实现代码添加到 AnagramsStats JMX 标准 MBean 中</h2>
<p>在本练习中,将某种内部逻辑添加到 <tt>AnagramsStats</tt> MBean 类实现中。 </p>
<p>请执行以下步骤以添加实现代码。</p>
<ol>
<li>已声明属性的私有字段,无需向属性的 getter 方法中添加任何内容。</li>
<li>需要实现 <tt>resetAll()</tt> 方法。生成的主体为空。调用 <tt>resetAll()</tt> 时,我们简单地将所有计数器都设置为 0。在 <tt>resetAll()</tt> 方法主体中添加以下代码行(粗体):
<pre>public void resetAll() {
<strong>minThinkingTime = 0;
maxThinkingTime = 0;
lastThinkingTime = 0;
numSolvedAnagrams = 0;</strong>
}</pre>
</li>
<li>您还需要添加将执行以下操作的某种实现代码:
<ul>
<li>计算用户解决最后一个 Anagram 所用的思考时间,</li>
<li>计算最短和最长的思考时间,</li>
<li>增加已解决 Anagram 的计数器,</li>
<li>知道哪个是当前 Anagram,</li>
<li>当 Anagram 得到解决时创建并发送通知。</li>
</ul>
<p>出于该目的,将添加一个私有字段 <tt>startTime</tt>(用于存储将最后一个 Anagram 提供给用户的时间)、<tt>startThinking()</tt><tt>stopThinking()</tt> 两个方法(用于执行以上列出的操作)和一个 <tt>setCurrentAnagram()</tt> 方法。</p>
<p>例如,将以下代码添加到 <tt>AnagramsStats.java</tt> 中的类实现结尾。
<pre class="examplecode">
/*
* Methods exposed to Anagrams application to feed management with data.
*/
//Stores the time at which a new anagram is proposed to the user.
private long startTime;
/**
* A new Anagram is proposed to the user: store current time.
*/
public void startThinking() {
startTime = System.currentTimeMillis();
}
/**
* An Anagram has been resolved.
*/
public void stopThinking() {
//Update the number of resolved anagrams
numSolvedAnagrams++;
// Compute last, min and max thinking times
lastThinkingTime = (int) (System.currentTimeMillis() - startTime) / 1000 ;
minThinkingTime = (lastThinkingTime < minThinkingTime || minThinkingTime == 0) ?
lastThinkingTime :
minThinkingTime;
maxThinkingTime = (lastThinkingTime > maxThinkingTime) ?
lastThinkingTime :
maxThinkingTime;
//Create a JMX Notification
Notification notification = new Notification(AttributeChangeNotification.ATTRIBUTE_CHANGE,
this,
getNextSeqNumber(),
"Anagram solved: " + currentAnagram);
// Send a JMX notification.
broadcaster.sendNotification(notification);
}
/**
* Set latest anagram which has been computed by the Anagram application
*/
public void setCurrentAnagram(String currentAnagram) {
this.currentAnagram = currentAnagram;
}</pre>
<p>请注意,<tt>startThinking()</tt><tt>stopThinking()</tt><tt>setCurrentAnagram()</tt> 这三个方法不是 MBean 管理界面的一部分,因为未在 <tt>AnagramsStatsMBean</tt> 接口中声明这三个方法,但它们是公共方法,因为每次将新 Anagram 提供给用户时、Anagram 得到解决时、且为当前 Anagram 时,Anagram Game 应用程序就会调用这些方法以告知 MBean。因此,它们是应用程序与 MBean 之间的桥的必要部分。</p>
<p>另请注意,Anagram 每次得到解决时如何发送 <tt>ATTRIBUTE_CHANGE</tt> 类型的 JMX 通知。 </p>
</li>
</ol>
<p>您现已完成实现 MBean。在此部分中,您添加了代码和方法以允许以下操作:</p>
<ul>
<li>内部 MBean 状态更新</li>
<li>从应用程序调用</li>
<li>发送 JMX 通知</li>
</ul>
<a name="Exercise_5"></a>
<h2>练习 5:将管理和应用程序连接在一起</h2>
<p>在本练习中,我们将向 Anagram Game 应用程序中添加代码,以便该应用程序可以访问 MBean 以传递管理信息。</p>
<p>请执行以下步骤</p>
<ol>
<li>在编辑器中打开 <tt>Anagrams.java</tt>
<p><tt>com.toy.anagrams.ui</tt> 包中的 <tt>Anagrams</tt> 类是 Anagram Game 应用程序的<tt></tt>类。此文件将在编辑器的设计视图中打开,因为 <tt>Anagrams</tt> 类也是用户界面类。</p></li>
<li>单击 "Editor"(编辑器)窗口顶部的 "Source"(源)按钮以便在 "Source"(源)视图中编辑该类。</li>
<li>将以下空的 <tt>initManagement()</tt> 私有方法添加到 <tt>Anagrams</tt> 类中:<tt>Anagrams</tt> 构造函数后。
<pre>
/**
* JMX initialization:
* Create and register Anagrams MBean in Platform MBeanServer.
* Initialize thinking time and current anagram.
*/
private void initManagement() throws Exception {
}</pre>
</li>
<li>将以下对 <tt>initManagement()</tt> 方法的调用添加到 <tt>Anagrams</tt> 类构造函数结尾,在标记该构造函数结尾的结束花括号之前。
<pre>
//JMX Management initialization
initManagement();
</pre>
<p>您还需要将 <tt>throws Exception</tt> 子句添加到 <tt>Anagrams()</tt> 构造函数中,并将语句 <tt>new Anagrams().setVisible(true);</tt> 包含在要编译的 <tt>Main()</tt> 方法中的 try-catch 中。您可以在编辑器的左旁注中看到建议图标。您可以将插入光标放在代码行中,并键入 Alt-Enter 以在源代码编辑器中调用代码提示。</p>
<img alt="添加 try-catch 的代码提示" class="margin-around b-all" src="../../../images_www/articles/80/java/jmx/jmx-initmanagement-try.png" title="添加 try-catch 的代码提示">
<p>下面是您在此阶段应该看到的内容 [单击查看大图]:</p>
<a href="../../../images_www/articles/80/java/jmx/jmx-initmanagement.png" title="分析 Anagram 1 - 单击查看大图"><img alt="instrument_anagram1:添加 initManagement()" class="margin-around b-all" src="../../../images_www/articles/80/java/jmx/jmx-initmanagement-sm.png"></a>
</li>
<li>现在,我们使用 JMX 模块 MBean 注册向导将 MBean 注册代码添加到 <tt>initManagement()</tt> 方法中:
<p><tt>Anagrams.java</tt> 源代码编辑器窗口中,在 <tt>initManagement()</tt> 方法主体<strong>内部</strong>右键单击,选择 "JMX" 子菜单,然后选择 "Generate MBean Registration..."(生成 MBean 注册...)操作。在显示的 "Instantiate and Register MBean"(实例化并注册 MBean)面板中,保持 "Register Existing MBean"(注册现有 MBean)单选按钮为选中状态,单击 "Browse"(浏览)按钮,选择 <tt>AnagramsStats</tt> MBean 类,然后在 "Browse"(浏览)面板中单击 "OK"(确定)。此时您应该会看到:</p>
<img alt="create_mbean_registration:生成 MBean 注册代码" class="margin-around b-all" src="../../../images_www/articles/74/java/jmx/jmx-registermbeandialog.png">
<p>无需更改自动指定的 MBean 对象名称和构造函数。单击 "OK"(确定)后,您将会在 <tt>initManagement()</tt> 方法主体中看到生成的 MBean 注册代码。</p>
<hr style="width: 100%; height: 2px;" />
<h3>命名 MBean 的最佳实践</h3>
<ul>
<li>命名 MBean 时,在 "Object Name"(对象名)中使用 "<tt>type=</tt>" 关键字。此关键字的值应是 MBean 类(在我们的示例中为 <tt>AnagramsStats</tt>)。
</li>
<li>对于单一 MBean(在应用程序内具有单个实例的 MBean),具有此唯一关键字足以完成命名。
</li>
<li>避免创建太多的域名。使用您的应用程序 Java 包名。您也可以使用默认域名:不在 <tt>ObjectName</tt> "<tt>:</tt>" 分隔符之前指定域将隐式引用默认域。 </li>
</ul>
<p>应用最佳实践将使命名 MBean 的方式更加规范化。</p>
<p>因此,在上面我们的示例中,默认情况下创建的 <tt>ObjectName</tt> 是:<tt>com.toy.anagrams.mbeans:type=AnagramsStats</tt></p>
<hr style="width: 100%; height: 2px;"><br>
<p>在本教程的上下文中,需要一个额外步骤。您希望应用程序能够访问实现管理界面的类 (<tt>AnagramsStats</tt>)。这不是一般规则,但在应用程序需要将数据推入 MBean 中时会非常有用。在这种情况下,<tt>startThinking()</tt><tt>stopThinking()</tt><tt>setCurrentAnagram()</tt> 方法不是管理方法,但 Anagrams Game 应用程序会使用这些方法通知 MBean 发生了某些事件。然后,MBean 将更新其状态。要能够从 <tt>Anagrams</tt> UI 类访问 <tt>AnagramsStats</tt>,我们需要 <tt>Anagrams</tt> 类来直接引用 <tt>AnagramsStats</tt> MBean 的实例。</p>
<p>因此,您需要对 <tt>Anagrams.java</tt> 文件的代码进行以下更改。</p>
</li>
<li>将以下私有字段添加到 <tt>Anagrams</tt> 类中。
<pre>
// Reference to the AnagramsStats MBean
private AnagramsStats mbean;
</pre>
</li>
<li>通过修改生成的 MBean 注册代码,初始化对 <tt>initManagement()</tt> 方法中 <tt>AnagramsStats</tt> MBean 的引用,使其如下所示:
<pre>private void initManagement() throws Exception {
try { // Register MBean in Platform MBeanServer
<strong>mbean = new AnagramsStats();</strong>
ManagementFactory.getPlatformMBeanServer().
registerMBean(<strong>mbean</strong>,
new ObjectName("com.toy.anagrams.mbeans:type=AnagramsStats"));
} catch (JMException ex) {
<strong>ex.printStackTrace();</strong>
}</pre>
</li>
<li>初始化 <tt>AnagramsStats</tt> MBean 状态:当 Anagrams Game 应用程序启动时,将立即显示一个 anagram,因此我们需要向 MBean 传递 anagram 字符串值并开始计算思考时间。在 <tt>initManagement()</tt> 方法结尾处复制并粘贴以下行:<br />
<pre>
// When the Anagrams game is first displayed, a word is proposed to the user.
// We must start time computing and set the current anagram
mbean.startThinking();
mbean.setCurrentAnagram(wordLibrary.getScrambledWord(wordIdx));
</pre>
<p>下面是您在此阶段应该看到的内容 [单击查看大图]:</p>
<a href="../../../images_www/articles/74/java/jmx/jmx-initmanagement2.png" title="分析 Anagram 2 - 单击查看大图"><img alt="instrument_anagram1:添加 initManagement()" class="margin-around b-all" src="../../../images_www/articles/74/java/jmx/jmx-initmanagement2-sm.png"></a>
<p>您现在需要添加代码以跟踪用户的 anagram 解决体验。</p>
</li>
<li>找到 <tt>nextTrialActionPerformed()</tt> 方法,然后将以下代码粘贴到 <tt>nextTrialActionPerformed()</tt> 方法的结尾处。
<pre class="examplecode">
//Update management statistics and values
try {
mbean.setCurrentAnagram(wordLibrary.getScrambledWord(wordIdx));
mbean.startThinking();
} catch (Exception e) {e.printStackTrace();}</pre>
<p>每次向用户提供新的 Anagram 时,该代码就会告知 MBean 是哪一个 Anagram 并开始对用户思考时间进行计数。</p>
</li>
<li>找到 <tt>guessedWordActionPerformed()</tt> 方法并将以下行添加到代码中。保存所做的更改。
<pre class="examplecode">
//Update management stats
try {
mbean.stopThinking();
} catch(Exception e) {e.printStackTrace();}</pre>
<p>每次猜对 anagram 时都会调用 MBean 中的 <tt>stopThinking()</tt> 方法。</p>
<p>您现在应该会在编辑器中看到以下内容 [单击查看大图]:</p>
<a href="../../../images_www/articles/74/java/jmx/jmx-stopthinking.png" title="分析 Anagram 3 - 单击查看大图"><img alt="instrument_anagram3:调用 MBean 方法" class="margin-around b-all" src="../../../images_www/articles/74/java/jmx/jmx-stopthinking-sm.png"></a>
</li>
</ol>
<p>您现已完成将 JMX 管理层链接到应用程序层。在下一部分,您将构建并运行 Anagrams Game 应用程序,并通过 JConsole GUI 查看公开的管理信息。</p>
<a name="Exercise_6"></a>
<h2>练习 6:使用 JConsole 运行应用程序</h2>
<p>在此练习中,您将了解如何构建并运行项目,并连接 JConsole 以可视化 JVM 状态以及应用程序 MBean。 </p>
<p>请执行以下步骤以运行应用程序并查看管理信息。</p>
<ol>
<li>一个步骤即可执行这三项任务:只需单击工具栏中的 "Run Main Project with Monitoring and Management"(通过监视和管理运行主项目)按钮即可 (<img alt="工具栏中的 &amp;quot;Run Main Project with Monitoring and Management&amp;quot;(通过监视和管理运行主项目)按钮" src="../../../images_www/articles/74/java/jmx/run-project24.png" title="&amp;quot;Run Main Project with Monitoring and Management&amp;quot;(通过监视和管理运行主项目)按钮" />)
<p class="tips">您也可以从主菜单中的 "Run"(运行)菜单调用操作。</p>
<p class="notes"><strong>注:</strong>首次构建并运行应用程序时,IDE 将会显示一个警告对话框,通知您将更新 <tt>build.xml</tt> 文件。可以在该对话框中单击 "OK"(确定)。</p>
<img alt="警告对话框的屏幕快照" class="margin-around" src="../../../images_www/articles/74/java/jmx/jmx-firsttime.png" title="首次监视应用程序时的警告对话框" />
<p>您可以在 "Output"(输出)窗口中查看执行情况。</p>
<img alt="&quot;Output&quot;(输出)窗口的屏幕快照" class="margin-around" src="../../../images_www/articles/74/java/jmx/jmx-compiling.png" title="显示进程的 &amp;quot;Output&amp;quot;(输出)窗口" />
<p>IDE 将构建并启动 Anagram Game,并且将自动打开 JConsole 窗口。</p>
<img alt="Anagram Game 的屏幕快照" class="margin-around b-all" src="../../../images_www/articles/74/java/jmx/jmx-anagram.png" title="Anagram Game" />
<p class="notes"><strong>注:</strong>当 Java 监视和管理控制台尝试连接到 Anagram Game 进程时,您可能会在此控制台中看到 "Connection Failed"(连接失败)警告。对于本教程,当系统提示您授权连接时,您可以单击 "Insecure"(不安全)。</p>
</li>
<li>在 JConsole 窗口中选择 "MBean" 标签。</li>
<li>在左侧窗格的树布局中,展开 <tt>com.toy.anagrams.mbeans</tt> 下的所有节点。<br /> <img alt="显示 &amp;quot;AnagramsStats&amp;quot; 节点的 &amp;quot;MBean&amp;quot; 标签的屏幕快照" class="margin-around b-all" src="../../../images_www/articles/74/java/jmx/jmx-jconsole-mbeans1.png" title="显示 &amp;quot;AnagramsStats&amp;quot; 节点的 &amp;quot;MBean&amp;quot; 标签" />
</li>
<li>选择 "Notifications"(通知)节点,然后单击底部的 "Subscribe"(订阅)按钮,这样在 Anagram 每次得到解决时 JConsole 都将会收到新通知。</li>
<li>在 "Anagrams Game" 窗口中,解决前三个或前四个 Anagram。
<p class="tips">Anagram 的解决方案(abstraction、ambiguous、arithmetic、backslash...)包含在 <tt>WordLibrary</tt> 类中。</p></li>
<li>在 "JConsole" 窗口中,注意它收到了关于每个解决方案的通知。<br /> <a href="../../../images_www/articles/74/java/jmx/jmx-jconsole-mbeans2.png" title="单击查看大图"> <img alt="显示 &amp;quot;AnagramsStats&amp;quot; 节点的 &amp;quot;MBean&amp;quot; 标签的屏幕快照" class="margin-around b-all" src="../../../images_www/articles/74/java/jmx/jmx-jconsole-mbeans2-sm.png" title="显示 &amp;quot;AnagramsStats&amp;quot; 节点的 &amp;quot;MBean&amp;quot; 标签" /></a>
</li>
<li>单击 "Attributes"(属性)节点,可以看到更新了属性值:<br /> <img alt="显示 &amp;quot;AnagramsStats&amp;quot; 节点的 &amp;quot;MBean&amp;quot; 标签的屏幕快照" class="margin-around b-all" src="../../../images_www/articles/74/java/jmx/jmx-jconsole-mbeans3.png" title="显示 &amp;quot;AnagramsStats&amp;quot; 节点的 &amp;quot;MBean&amp;quot; 标签" />
<p>您可以试用 JConsole 界面和 Anagrams Game。例如,如果调用管理操作 <tt>resetAll()</tt>,您将会看到 MBean 属性值重置为 0。</p></li>
</ol>
<p><strong>现在,您完成了!您做得很棒,恭喜!</strong></p>
<div class="feedback-box">
<a href="/about/contact_form.html?to=3&amp;subject=Feedback:%20Adding%20Java%20Management%20Extensions%20(JMX)%20Instrumentation">发送有关此教程的反馈意见</a></div>
<br style="clear:both;">
<h2>另请参见</h2>
<p>有关详细信息,请参阅以下主题:</p>
<ul>
<li><a href="jmx-getstart.html">NetBeans IDE 中的 JMX 监视入门指南</a></li>
</ul>
</body>
</html>