﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-子在川上曰-随笔分类-JMX</title><link>http://www.blogjava.net/chengang/category/8015.html</link><description>　　　　逝者如斯乎不舍昼夜</description><language>zh-cn</language><lastBuildDate>Wed, 28 Feb 2007 02:51:52 GMT</lastBuildDate><pubDate>Wed, 28 Feb 2007 02:51:52 GMT</pubDate><ttl>60</ttl><item><title>[JMX一步步来]　9、基于JBoss来写MBean</title><link>http://www.blogjava.net/chengang/archive/2006/03/07/34091.html</link><dc:creator>陈刚</dc:creator><author>陈刚</author><pubDate>Tue, 07 Mar 2006 07:19:00 GMT</pubDate><guid>http://www.blogjava.net/chengang/archive/2006/03/07/34091.html</guid><wfw:comment>http://www.blogjava.net/chengang/comments/34091.html</wfw:comment><comments>http://www.blogjava.net/chengang/archive/2006/03/07/34091.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/chengang/comments/commentRss/34091.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chengang/services/trackbacks/34091.html</trackback:ping><description><![CDATA[<DIV align=center>　文/陈刚&nbsp; from <A href="http://www.chengang.com.cn/">www.chengang.com.cn</A> at 2005-12-26</DIV>
<DIV align=center>　</DIV>
<DIV>　　前面都是用JDK自带的JMX实现来写的MBean，JMX的实现不独SUN一家，JBOSS也有自己的JMX实现。如果你使用JBOSS来做WEB服务器，那么基于JBOSS的实现来写MBean，是一个不错的选择。象我们公司就是用JBOSS的，因此所有MBean都是基于JBoss来写的。基于JBoss的MBean和基于SUN的MBean有什么不同吗？有一些不同之外，但绝大部份都一样。</DIV>
<DIV>　</DIV>
<DIV></DIV>
<DIV>　　下面是我最早发的一篇关于JMX的文章，是我对公司所做项目的笔记，它上面的JMX例子就是基于JBOSS的。博客搬了几次家，文章删的删丢的丢，但这篇文章还保留着，简单修改一下，再帖上吧。</DIV>
<DIV></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV>
<H2 style="MARGIN: 12pt 0cm"><FONT size=3><SPAN><FONT face=Arial><SPAN style="mso-spacerun: yes">一、&nbsp; </SPAN>HelloWorld</FONT></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">实例</SPAN></FONT><SPAN> 
<P></P></SPAN></H2>
<H3 style="MARGIN: 12pt 0cm 6pt"><SPAN><FONT face="宋体, MS Song" size=2>1、准备工作</FONT></SPAN></H3>
<P><FONT size=2><SPAN><FONT face="Times New Roman">　　JBOSS</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">实现了</SPAN><SPAN><FONT face="Times New Roman">JMX</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">规范，这个实例是基于</SPAN><SPAN><FONT face="Times New Roman">JBOSS</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">来实现的。请先去下载一个</SPAN><SPAN><FONT face="Times New Roman">JBOSS</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">，我是</SPAN><SPAN><FONT face="Times New Roman">jboss-3.2.6</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">，下载地址：</SPAN><SPAN><A href="http://www.jboss.com/downloads/index#as"><FONT face="Times New Roman">http://www.jboss.com/downloads/index#as</FONT></A></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">。这个实例需要</SPAN><SPAN><FONT face="Times New Roman">JBOSS</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">的两个</SPAN><SPAN><FONT face="Times New Roman">JAR</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">包的支持：</SPAN><SPAN><FONT face="Times New Roman">jboss-system-3.2.6.jar</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">、</SPAN><SPAN><FONT face="Times New Roman">jboss-jmx-3.2.6.jar</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">，如果你和我一样用</SPAN><SPAN><FONT face="Times New Roman">Eclipse</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">来开发（推荐），那么把这个两个包加入到项目的库引用中（加入到库引用的方法参考前面两章）。</SPAN></FONT></P>
<H3 style="MARGIN: 12pt 0cm 6pt"><SPAN><FONT face="宋体, MS Song" size=2>2、程序代码</FONT></SPAN></H3>
<P><FONT size=3><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">　　<FONT size=2>假设我们有一个叫</FONT></SPAN></FONT><FONT size=2><SPAN><FONT face="Times New Roman">message</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">的属性要需要经常进行改动配置的，那么我们就把它写成一个</SPAN><SPAN><FONT face="Times New Roman">MBean</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">。</SPAN></FONT></P>
<P><FONT size=2><SPAN><FONT face="Times New Roman">1</FONT></SPAN><SPAN style="FONT-FAMILY: 楷体_GB2312; mso-ascii-font-family: ">、</SPAN><SPAN><FONT face="Times New Roman">HelloWorldServiceMBean</FONT></SPAN><SPAN style="FONT-FAMILY: 楷体_GB2312; mso-ascii-font-family: ">接口</SPAN></FONT></P>
<P><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">　　在写</SPAN><SPAN><FONT face="Times New Roman">MBean</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">之前，我们先需要写一个</SPAN><SPAN><FONT face="Times New Roman">MBean</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">接口，接口里的方法都是属性的</SPAN><SPAN><FONT face="Times New Roman">set/get</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">方法。这个接口必须继承接口</SPAN><SPAN><FONT face="Times New Roman">ServiceMBean</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">。</SPAN></FONT></P>
<DIV style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 4pt; BACKGROUND: #ffead5; PADDING-BOTTOM: 1pt; BORDER-LEFT: windowtext 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt"><SPAN><FONT face="Courier New" size=2><BR></FONT></SPAN><SPAN><FONT face="Courier New" size=2>import org.jboss.system.ServiceMBean;<BR></FONT></SPAN><SPAN><FONT face="Courier New" size=2>public interface HelloWorldServiceMBean extends ServiceMBean {<BR></FONT></SPAN><SPAN><FONT size=2><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>String getMessage();<BR></FONT></FONT></SPAN><SPAN><FONT size=2><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>void setMessage(String message);<BR></FONT></FONT></SPAN><SPAN><FONT face="Courier New" size=2>}</FONT></SPAN></DIV>
<P><FONT size=2><SPAN>2</SPAN><FONT face=宋体><SPAN style="FONT-FAMILY: 楷体_GB2312; mso-ascii-font-family: ">、</SPAN><SPAN>HelloWorldService</SPAN><SPAN style="FONT-FAMILY: 楷体_GB2312; mso-ascii-font-family: ">实现类</SPAN></FONT></FONT></P>
<P><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">　　然后写出</SPAN><SPAN>HelloWorldServiceMBean</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">接口的实现类</SPAN><SPAN>HelloWorldService</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">，这个实现类还必须继承</SPAN><SPAN>ServiceMBeanSupport</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">类。</SPAN></FONT><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">这种类再简单不过了，就是属性和相应的</SPAN><SPAN>set/get</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">方法，</SPAN><SPAN>EJB</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">中叫实体类、</SPAN><SPAN>Hibernate</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">中叫</SPAN><SPAN>POJO</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">。</SPAN><SPAN></SPAN></FONT></P>
<P></P>
<DIV style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 4pt; BACKGROUND: #ffead5; PADDING-BOTTOM: 1pt; BORDER-LEFT: windowtext 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt">
<P><SPAN></SPAN></P>
<P></P>
<P><SPAN><FONT face="Courier New" size=2>import org.jboss.system.ServiceMBeanSupport;<BR></FONT></SPAN><SPAN><FONT face="Courier New" size=2>public class HelloWorldService extends ServiceMBeanSupport implements HelloWorldServiceMBean {<BR></FONT></SPAN><SPAN><FONT size=2><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>private String message;<BR></FONT></FONT></SPAN><SPAN><FONT size=2><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>public String getMessage() {<BR></FONT></FONT></SPAN><SPAN><FONT size=2><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println("getMessage()=" + message);<BR></FONT></FONT></SPAN><SPAN><FONT size=2><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>return message;<BR></FONT></FONT></SPAN><SPAN><FONT size=2><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>}</FONT></FONT></SPAN></P>
<P><SPAN></SPAN></P>
<P></P>
<P><SPAN><FONT size=2><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>public void setMessage(String message) {<BR></FONT></FONT></SPAN><SPAN><FONT size=2><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println("setMessage(" + message + ")");<BR></FONT></FONT></SPAN><SPAN><FONT size=2><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>this.message = message;<BR></FONT></FONT></SPAN><SPAN><FONT size=2><FONT face="Courier New"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>}<BR></FONT></FONT></SPAN><SPAN><FONT face="Courier New" size=2>}</FONT></SPAN></P></DIV>
<P><FONT size=2><SPAN>3</SPAN><FONT face=宋体><SPAN style="FONT-FAMILY: 楷体_GB2312; mso-ascii-font-family: ">、配置文件</SPAN><SPAN>jboss-service.xml</SPAN></FONT></FONT></P>
<P></P>
<DIV style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 4pt; BACKGROUND: #ffead5; PADDING-BOTTOM: 1pt; BORDER-LEFT: windowtext 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt">
<P><SPAN><FONT face="Courier New" size=2>&lt;?xml version="1.0" encoding="UTF-8"?&gt;<BR></FONT></SPAN><SPAN><FONT face="Courier New" size=2>&lt;server&gt;<BR></FONT></SPAN><SPAN><FONT size=2><FONT face="Courier New"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </SPAN>&lt;mbean code="example.mbean.HelloWorldService" name="www.chengang.com.cn:service=HelloWorld"&gt;<BR></FONT></FONT></SPAN><SPAN><FONT size=2><FONT face="Courier New"><SPAN style="mso-tab-count: 2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>&lt;attribute name="Message"&gt;Hello World&lt;/attribute&gt;<BR></FONT></FONT></SPAN><SPAN><FONT size=2><FONT face="Courier New"><SPAN style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </SPAN>&lt;/mbean&gt;<BR></FONT></FONT></SPAN><SPAN><FONT face="Courier New" size=2>&lt;/server&gt;</FONT></SPAN></P></DIV>
<P><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: "><FONT size=2>说明：</FONT></SPAN></P>
<P><FONT size=2><SPAN style="FONT-SIZE: 7.5pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT-WEIGHT: normal; FONT-SIZE: 7pt; LINE-HEIGHT: normal; FONT-STYLE: normal; FONT-VARIANT: normal">&nbsp;</SPAN></SPAN></SPAN><SPAN><FONT face="Times New Roman">code</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">项指向</SPAN><SPAN><FONT face="Times New Roman">MBean</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">的实现类</SPAN><SPAN><FONT face="Times New Roman">HelloWorldService<BR></FONT></SPAN></FONT><FONT size=2><SPAN style="FONT-SIZE: 7.5pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT-WEIGHT: normal; FONT-SIZE: 7pt; LINE-HEIGHT: normal; FONT-STYLE: normal; FONT-VARIANT: normal">&nbsp;</SPAN></SPAN></SPAN><SPAN><FONT face="Times New Roman">name</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">项是一个名称，格式一般是：</SPAN><SPAN><FONT face="Times New Roman">[</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">说明性文字</SPAN><SPAN><FONT face="Times New Roman">]:service=[</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">类名</SPAN><SPAN><FONT face="Times New Roman">]<BR></FONT></SPAN></FONT><FONT size=2><SPAN style="FONT-SIZE: 7.5pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT-WEIGHT: normal; FONT-SIZE: 7pt; LINE-HEIGHT: normal; FONT-STYLE: normal; FONT-VARIANT: normal">&nbsp;</SPAN></SPAN></SPAN><SPAN><FONT face="Times New Roman">attribute</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">是为属性设置初始值，这样当</SPAN><SPAN><FONT face="Times New Roman">JBOSS</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">一加载</SPAN><SPAN><FONT face="Times New Roman">HelloWorldService</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">类时，</SPAN><SPAN><FONT face="Times New Roman">message</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">属性就有了一个初始值</SPAN><SPAN><FONT face="Times New Roman">Hello World</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">。注意</SPAN><SPAN><FONT face="Times New Roman">Message</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">的第一个字母必须是大写。</SPAN></FONT></P>
<H3 style="MARGIN: 12pt 0cm 6pt"><SPAN><FONT face="宋体, MS Song" size=3>二、将实例部署到JBOSS</FONT></SPAN></H3>
<P><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">　　在</SPAN><SPAN><FONT face="Times New Roman">jboss-3.2.6\server\default\deploy</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">目录下创建一个</SPAN><SPAN><FONT face="Times New Roman">hello.sar</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">目录，然后创建如下目录文件结构：</SPAN></FONT></P>
<P><SPAN><FONT face="Times New Roman" size=2>hello.sar<BR></FONT></SPAN><SPAN><FONT face="Times New Roman" size=2>|----example<BR></FONT></SPAN><SPAN><FONT face="Times New Roman" size=2>|<SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; |</SPAN>----mbean<BR></FONT></SPAN><FONT size=2><SPAN><FONT face="Times New Roman">|<SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;|</SPAN>----HelloWorldService.class<SPAN style="mso-spacerun: yes">&nbsp; </SPAN>(</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">注意：是</SPAN><SPAN><FONT face="Times New Roman">*.class</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">，不是</SPAN><SPAN><FONT face="Times New Roman">*.java)<BR></FONT></SPAN></FONT><SPAN><FONT face="Times New Roman" size=2>|<SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |</SPAN>----HelloWorldServiceMBean.class<BR></FONT></SPAN><SPAN><FONT face="Times New Roman" size=2>|----META-INF<BR></FONT></SPAN><SPAN><FONT face="Times New Roman" size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |----jboss-service.xml</FONT></SPAN></P>
<P><FONT size=2></FONT></P>
<P><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: "><FONT size=2>其他说明：</FONT></SPAN></P>
<P><FONT size=2><SPAN style="FONT-SIZE: 7.5pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT-WEIGHT: normal; FONT-SIZE: 7pt; LINE-HEIGHT: normal; FONT-STYLE: normal; FONT-VARIANT: normal">&nbsp;</SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">也可以将</SPAN><SPAN><FONT face="Times New Roman">hello.sar</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">目录用</SPAN><SPAN><FONT face="Times New Roman">zip</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">格式压缩成一个同名的</SPAN><SPAN><FONT face="Times New Roman">hello.sar</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">文件，放到</SPAN><SPAN><FONT face="Times New Roman">jboss-3.2.6\server\default\deploy</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">目录下。<BR></SPAN></FONT><FONT size=2><SPAN style="FONT-SIZE: 7.5pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT-WEIGHT: normal; FONT-SIZE: 7pt; LINE-HEIGHT: normal; FONT-STYLE: normal; FONT-VARIANT: normal">&nbsp;</SPAN></SPAN></SPAN><SPAN><FONT face="Times New Roman">JBOSS</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">支持热部署，也就是说你在布置这个目录时并不需要重启</SPAN><SPAN><FONT face="Times New Roman">JBOSS</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">。</SPAN></FONT></P>
<H3 style="MARGIN: 12pt 0cm 6pt"><SPAN><FONT face="宋体, MS Song"><FONT size=3>三、MBean的效果</FONT> 
<P></P></FONT></SPAN><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">打开网址：</SPAN><SPAN><A href="http://127.0.0.1:8080/jmx-console/"><FONT face="Times New Roman">http://127.0.0.1:8080/jmx-console/</FONT></A></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">　，出现下图</SPAN><SPAN></SPAN></FONT></H3>
<P><FONT size=2></FONT></P>
<P><FONT size=2><SPAN><IMG style="DISPLAY: block; MARGIN: 0px auto 10px; TEXT-ALIGN: center" alt=1135588829669_6124.jpg src="http://blog.sohu.com/images/person/2005/12/26/1135588829669_6124.jpg" border=0></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">然后单击“</SPAN><SPAN><FONT face="Times New Roman">service=HelloWorld</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">”项打开详细页面如下：</SPAN></FONT></P>
<P><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: "><FONT size=2><IMG style="DISPLAY: block; MARGIN: 0px auto 10px; TEXT-ALIGN: center" alt=1135588871713_5327.jpg src="http://blog.sohu.com/images/person/2005/12/26/1135588871713_5327.jpg" border=0></FONT></SPAN></P>
<P><SPAN><FONT size=2></FONT></SPAN></P>
<P><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">将“</SPAN><SPAN><FONT face="Times New Roman">HelloWorld</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">”改成“</SPAN><SPAN><FONT face="Times New Roman">Hello World</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">，</SPAN><SPAN><FONT face="Times New Roman">ChenGang</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">”，再单击“</SPAN><SPAN><FONT face="Times New Roman">Apply Changes</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">”应用修改，得到如下效果：</SPAN></FONT></P>
<P><SPAN><FONT size=2></FONT></SPAN></P>
<H2 style="MARGIN: 12pt 0cm"><SPAN><FONT face=Arial size=2><IMG style="DISPLAY: block; MARGIN: 0px auto 10px; TEXT-ALIGN: center" alt=1135588893639_3324.jpg src="http://blog.sohu.com/images/person/2005/12/26/1135588893639_3324.jpg" border=0></FONT></SPAN></H2>
<H2 style="MARGIN: 12pt 0cm"><FONT size=3><SPAN>四、</SPAN><FONT face=宋体><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">其他类如何使用</SPAN><SPAN>Messag</SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">属性</SPAN></FONT></FONT></H2>
<P><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">　　现在我们可以通过一个自动提供的</SPAN><SPAN><FONT face="Times New Roman">WEB</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">页面来设置</SPAN><SPAN><FONT face="Times New Roman">Message</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">属性了，接下来的问题是：“在其他类中应该如何得到</SPAN><SPAN><FONT face="Times New Roman">Message</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">的属性值”。</SPAN><SPAN><FONT face="Times New Roman">MBean</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">在</SPAN><SPAN><FONT face="Times New Roman">JBoss</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">是只保留一个</SPAN><SPAN><FONT face="Times New Roman">MBean</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">的实例（单例模式？），也就是说问题转成我们如何去取得这个唯一实例。例程如下：</SPAN></FONT></P>
<P><FONT size=2><SPAN><FONT face="Times New Roman">1</FONT></SPAN><SPAN style="FONT-FAMILY: 楷体_GB2312; mso-ascii-font-family: ">、创建一个使用到</SPAN><SPAN><FONT face="Times New Roman">Message</FONT></SPAN><SPAN style="FONT-FAMILY: 楷体_GB2312; mso-ascii-font-family: ">属性的类</SPAN></FONT></P>
<DIV style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 4pt; BACKGROUND: #ffead5; PADDING-BOTTOM: 1pt; BORDER-LEFT: windowtext 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt">
<P><SPAN><FONT face="Courier New" size=2></FONT></SPAN></P>
<P><SPAN><FONT size=2></FONT></SPAN></P>
<P><FONT size=2></FONT></P><SPAN><FONT face="Courier New" size=2>import org.jboss.mx.util.MBeanProxyExt;<BR></FONT></SPAN><SPAN><FONT face="Courier New" size=2>import org.jboss.mx.util.ObjectNameFactory;<BR></FONT></SPAN><SPAN><FONT face="Courier New" size=2>public class Client {<BR></FONT></SPAN><SPAN><FONT face="Courier New"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>public void go() {<BR></FONT></FONT></SPAN><SPAN><FONT face="Courier New"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>HelloWorldServiceMBean mbean = (HelloWorldServiceMBean) MBeanProxyExt.create(HelloWorldServiceMBean.class, ObjectNameFactory.create(<A href="http://www.chengang.com.cn:service=HelloWorld/">www.chengang.com.cn:service=HelloWorld</A>));<BR></FONT></FONT></SPAN><SPAN><FONT face="Courier New"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;</SPAN><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN>String msg = mbean.getMessage();<BR></FONT></FONT></SPAN><SPAN><FONT face="Courier New"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>System.out.println("Client.go()=" + msg);<BR></FONT></FONT></SPAN><SPAN><FONT face="Courier New"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>}<BR></FONT></FONT></SPAN><SPAN><FONT face="Courier New" size=2>}</FONT></SPAN><FONT face="Courier New" size=2>&nbsp;</FONT></DIV>
<P><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">注意：</SPAN><SPAN><FONT face="Times New Roman">go</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">方法里是三句。第一句比较长，它是根据</SPAN><SPAN><FONT face="Times New Roman">jboss-service.xml</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">文件中设置的</SPAN><SPAN><FONT face="Times New Roman">MBean</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">名称，来取得此</SPAN><SPAN><FONT face="Times New Roman">MBean</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">在</SPAN><SPAN><FONT face="Times New Roman">JBOSS</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">中的实例。</SPAN><SPAN></SPAN></FONT></P>
<P><FONT size=2></FONT></P>
<P><FONT size=2><SPAN><FONT face="Times New Roman">2</FONT></SPAN><SPAN style="FONT-FAMILY: 楷体_GB2312; mso-ascii-font-family: ">、在</SPAN><SPAN><FONT face="Times New Roman">Mbean</FONT></SPAN><SPAN style="FONT-FAMILY: 楷体_GB2312; mso-ascii-font-family: ">中加一个相应的调用</SPAN><SPAN><FONT face="Times New Roman">Client.go</FONT></SPAN><SPAN style="FONT-FAMILY: 楷体_GB2312; mso-ascii-font-family: ">的方法</SPAN></FONT></P>
<P><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">　在</SPAN><SPAN><FONT face="Times New Roman">HelloWorldServiceMBean</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">接口中加入一句：</SPAN></FONT></P>
<DIV style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 4pt; BACKGROUND: #ffead5; PADDING-BOTTOM: 1pt; BORDER-LEFT: windowtext 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt">
<P><SPAN><FONT face="Courier New" size=2>void callGo();</FONT></SPAN></P></DIV>
<P><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">在</SPAN><SPAN><FONT face="Times New Roman">HelloWorldService</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">类中加入现实方法：</SPAN></FONT></P>
<DIV style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 4pt; BACKGROUND: #ffead5; PADDING-BOTTOM: 1pt; BORDER-LEFT: windowtext 1pt solid; PADDING-TOP: 1pt; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt">
<P><SPAN><FONT face="Courier New"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>public void callGo() {<BR></FONT></FONT></SPAN><SPAN><FONT face="Courier New"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>new Client().go();<BR></FONT></FONT></SPAN><SPAN><FONT face="Courier New"><FONT size=2><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>}</FONT></FONT></SPAN></P></DIV>
<P><FONT size=2><SPAN><FONT face="Times New Roman">3</FONT></SPAN><SPAN style="FONT-FAMILY: 楷体_GB2312; mso-ascii-font-family: ">、更新布署</SPAN></FONT></P>
<P><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">&nbsp;&nbsp; 将三个类的</SPAN><SPAN><FONT face="Times New Roman">class</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">文件：</SPAN><SPAN><FONT face="Times New Roman">Clien.class</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">、</SPAN><SPAN><FONT face="Times New Roman">HelloWorldServiceMBean.class</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">、</SPAN><SPAN><FONT face="Times New Roman">HelloWorldService.class</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">，更新到</SPAN><SPAN><FONT face="Times New Roman">JBOSS</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">的</SPAN><SPAN><FONT face="Times New Roman">hello.sar\example\mbean</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">目录下。然后重启</SPAN><SPAN><FONT face="Times New Roman">JBOSS</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">。</SPAN></FONT></P>
<P><FONT size=2><SPAN><FONT face="Times New Roman">4</FONT></SPAN><SPAN style="FONT-FAMILY: 楷体_GB2312; mso-ascii-font-family: ">、查看效果</SPAN></FONT></P>
<P><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">&nbsp;&nbsp; 打开</SPAN><SPAN><FONT face="Times New Roman">JBOSS</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">提供的</SPAN><SPAN><FONT face="Times New Roman">MBean</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">设置页面，如下，发现多了一个</SPAN><SPAN><FONT face="Times New Roman">callGo</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">。</SPAN></FONT></P>
<P><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: "><FONT size=2><IMG style="DISPLAY: block; MARGIN: 0px auto 10px; TEXT-ALIGN: center" alt=1135589421532_8527.jpg src="http://blog.sohu.com/images/person/2005/12/26/1135589421532_8527.jpg" border=0></FONT></SPAN></P>
<P><SPAN><FONT size=2></FONT></SPAN></P>
<P><FONT size=2></FONT></P>
<P><FONT size=2><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">单击</SPAN><SPAN><FONT face="Times New Roman">callGo</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">项后的</SPAN><SPAN><FONT face="Times New Roman">invoke</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">按钮，得到如下的</SPAN><SPAN><FONT face="Times New Roman">DOS</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">输出：</SPAN></FONT></P>
<P><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: "><FONT size=2><IMG style="DISPLAY: block; MARGIN: 0px auto 10px; TEXT-ALIGN: center" alt=1135589435968_2575.jpg src="http://blog.sohu.com/images/person/2005/12/26/1135589435968_2575.jpg" border=0></FONT></SPAN></P>
<P><SPAN><FONT size=2></FONT></SPAN></P>
<H2 style="MARGIN: 12pt 0cm"><FONT size=3><SPAN>五、</SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial"><FONT face=宋体>其他说明</FONT></SPAN></FONT></H2>
<P><FONT size=2><SPAN style="FONT-SIZE: 7.5pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT-WEIGHT: normal; FONT-SIZE: 7pt; LINE-HEIGHT: normal; FONT-STYLE: normal; FONT-VARIANT: normal">&nbsp;</SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">本实例仅演示了一个</SPAN><SPAN><FONT face="Times New Roman">Message</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">属性，你当然可以在</SPAN><SPAN><FONT face="Times New Roman">HelloWorldService</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">中加入更多属性，别忘了在</SPAN><SPAN><FONT face="Times New Roman">HelloWorldServiceMBean</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">接口也加入相应的</SPAN><SPAN><FONT face="Times New Roman">set/get</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">方法。<BR></SPAN></FONT><FONT size=2><SPAN style="FONT-SIZE: 7.5pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT-WEIGHT: normal; FONT-SIZE: 7pt; LINE-HEIGHT: normal; FONT-STYLE: normal; FONT-VARIANT: normal">&nbsp;</SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">本实例的</SPAN><SPAN><FONT face="Times New Roman">message</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">属性是</SPAN><SPAN><FONT face="Times New Roman">String</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">类型的，但</SPAN><SPAN><FONT face="Times New Roman">JMX</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">也支持其他的类型，甚至是</SPAN><SPAN><FONT face="Times New Roman">XML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">信息。对于</SPAN><SPAN><FONT face="Times New Roman">jboss-service.xml</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">中的</SPAN><SPAN><FONT face="Times New Roman">XML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">信息，这时属性类型要求是</SPAN><SPAN><FONT face="Times New Roman">org.w3c.dom.Element</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">，</SPAN><SPAN><FONT face="Times New Roman">JMX</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">将它封装成了一个</SPAN><SPAN><FONT face="Times New Roman">XML</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">的</SPAN><SPAN><FONT face="Times New Roman">DOM</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">对象。<BR></SPAN></FONT><FONT size=2><SPAN style="FONT-SIZE: 7.5pt; FONT-FAMILY: Wingdings; mso-fareast-font-family: Wingdings; mso-bidi-font-size: 10.5pt; mso-bidi-font-family: Wingdings"><SPAN style="mso-list: Ignore">l<SPAN style="FONT-WEIGHT: normal; FONT-SIZE: 7pt; LINE-HEIGHT: normal; FONT-STYLE: normal; FONT-VARIANT: normal">&nbsp;</SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">回顾一下，</SPAN><SPAN><FONT face="Times New Roman">JMX</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">也是将配置信息写在了一个文件（</SPAN><SPAN><FONT face="Times New Roman">jboss-service.xml</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">文件）里嘛，相对于将配置文件写到</SPAN><SPAN><FONT face="Times New Roman">*.properties</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">文件的方式，它似乎也没什么新鲜的地方。但通过本章实例我们可以看到</SPAN><SPAN><FONT face="Times New Roman">JMX</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">的一些好处：我们不用写代码去读配置文件的信息，而且</SPAN><SPAN><FONT face="Times New Roman">JMX</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">支持的属性类型是多种多样的（如上面说的</SPAN><SPAN><FONT face="Times New Roman">org.w3c.dom.Element</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">）。更重要的是</SPAN><SPAN><FONT face="Times New Roman">JMX</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">还提供了一整套的属性之前互相访问、互相调用的功能，这个</SPAN><SPAN><FONT face="Times New Roman">HelloWorld</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: ">实例所反映的只是冰山一角而已。</SPAN><SPAN></SPAN></FONT></P>
<P><FONT size=2></FONT></P>
<H2 style="MARGIN: 12pt 0cm"><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial"><FONT face=宋体 size=3>六、参考资料：</FONT></SPAN><SPAN><A href="http://www.huihoo.com/java/jmx/jmx_base.html"><FONT face="Times New Roman" size=2>http://www.huihoo.com/java/jmx/jmx_base.html</FONT></A><FONT size=2>　</FONT></SPAN><SPAN></SPAN></H2>
<P></P>
<P></P>
<P></P>
<P></P>
<P></P>
<P></P>
<P></P>
<P></P>
<P></P>
<P></P>
<P></P>
<P></P>
<P></P>
<P></P>
<P></P>
<P></P>
<P></P>
<P></P>
<P></P>
<P></P>
<P></P>
<P></P>
<DIV>
<P><STRONG><FONT size=3>七、作者简介</FONT></STRONG></P>
<P>陈刚，广西桂林人，著作有《Eclipse从入门到精通》<BR>您可以通过其博客了解更多信息和文章：<A href="http://www.chengang.com.cn/"><FONT color=#000033>http://www.chenGang.com.cn</FONT></A> </P></DIV></DIV><img src ="http://www.blogjava.net/chengang/aggbug/34091.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chengang/" target="_blank">陈刚</a> 2006-03-07 15:19 <a href="http://www.blogjava.net/chengang/archive/2006/03/07/34091.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[JMX一步步来]　8、编写程序来连接MBean</title><link>http://www.blogjava.net/chengang/archive/2006/03/07/34089.html</link><dc:creator>陈刚</dc:creator><author>陈刚</author><pubDate>Tue, 07 Mar 2006 07:17:00 GMT</pubDate><guid>http://www.blogjava.net/chengang/archive/2006/03/07/34089.html</guid><wfw:comment>http://www.blogjava.net/chengang/comments/34089.html</wfw:comment><comments>http://www.blogjava.net/chengang/archive/2006/03/07/34089.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/chengang/comments/commentRss/34089.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chengang/services/trackbacks/34089.html</trackback:ping><description><![CDATA[<DIV align=center>文/陈刚&nbsp; from <A href="http://www.chengang.com.cn/">www.chengang.com.cn</A> at 2005-12-26</DIV>
<DIV align=center>　</DIV>
<DIV>　　前面用Html、jconsole等方法连接上了MBeanServer，并能够通过这些界面来操纵MBean。但有时我们需要不借助这些客户端，而是在自己的程序来操纵这些MBean，这就要求我们知道如何在代码里连接MBean。</DIV>
<DIV>　</DIV>
<DIV>　　基于上一篇为jconsole而修改的例子，给出一个示例的客户端程序，基本的操作都有了：</DIV>
<DIV>
<DIV></DIV>
<DIV>
<DIV>
<DIV style="BORDER-RIGHT: 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 1px; BORDER-LEFT: 1px solid; WIDTH: 100%; PADDING-TOP: 1px; BORDER-BOTTOM: 1px solid; HEIGHT: 18px"><PRE><BR>import java.util.Iterator;<BR>import java.util.Set;</PRE><PRE>import javax.management.Attribute;<BR>import javax.management.MBeanInfo;<BR>import javax.management.MBeanServerConnection;<BR>import javax.management.MBeanServerInvocationHandler;<BR>import javax.management.ObjectInstance;<BR>import javax.management.ObjectName;<BR>import javax.management.remote.JMXConnector;<BR>import javax.management.remote.JMXConnectorFactory;<BR>import javax.management.remote.JMXServiceURL;</PRE><PRE>public class Client {</PRE><PRE>&nbsp;&nbsp;&nbsp; public static void main(String[] args) throws Exception {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/server");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JMXConnector jmxc = JMXConnectorFactory.connect(url, null);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ObjectName mbeanName = new ObjectName("chengang:name=HelloWorld");</PRE><PRE>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //把所有Domain都打印出来<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Domains:---------------");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String domains[] = mbsc.getDomains();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; domains.length; i++) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("\tDomain[" + i + "] = " + domains[i]);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</PRE><PRE>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //MBean的总数<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("MBean count = " + mbsc.getMBeanCount());</PRE><PRE>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //对name属性的操作（属性名的第一个字母要大写）<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mbsc.setAttribute(mbeanName, new Attribute("Name", "Chen.Gang"));//设值<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Name = " + mbsc.getAttribute(mbeanName, "Name"));//取值</PRE><PRE>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //得到proxy代理后直接调用的方式<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HelloMBean proxy = (HelloMBean) MBeanServerInvocationHandler.newProxyInstance(mbsc, mbeanName, HelloMBean.class, false);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; proxy.printHello();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; proxy.printHello("陈刚");</PRE><PRE>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //远程调用的方式<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mbsc.invoke(mbeanName, "printHello", null, null);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mbsc.invoke(mbeanName, "printHello", new Object[] { "子在川上曰" }, new String[] { String.class.getName() });</PRE><PRE>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //得mbean的信息<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MBeanInfo info = mbsc.getMBeanInfo(mbeanName);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Hello Class: " + info.getClassName());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Hello Attriber：" + info.getAttributes()[0].getName());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Hello Operation：" + info.getOperations()[0].getName());</PRE><PRE>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //得到所有的MBean的ObjectName<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("all ObjectName：---------------");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Set set = mbsc.queryMBeans(null, null);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (Iterator it = set.iterator(); it.hasNext();) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ObjectInstance oi = (ObjectInstance) it.next();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("\t" + oi.getObjectName());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</PRE><PRE>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //注销<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //mbsc.unregisterMBean(mbeanName);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //关闭MBeanServer连接<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jmxc.close();<BR>&nbsp;&nbsp;&nbsp; }<BR>}<BR></PRE></DIV></DIV>
<DIV>　</DIV>
<DIV>运行后的效果如下：</DIV>
<DIV></DIV>
<DIV>Domains:---------------<BR>&nbsp;Domain[0] = HelloAgent<BR>&nbsp;Domain[1] = JMImplementation<BR>&nbsp;Domain[2] = chengang<BR>MBean count = 3<BR>Name = Chen.Gang<BR>Hello Class: mbean.connector.Hello<BR>Hello Attriber：Name<BR>Hello Operation：printHello<BR>all ObjectName：---------------<BR>&nbsp;chengang:name=HelloWorld<BR>&nbsp;JMImplementation:type=MBeanServerDelegate<BR>&nbsp;HelloAgent:name=htmladapter,port=8082</DIV>
<DIV>　</DIV>
<DIV>　</DIV>
<DIV><STRONG>它有两个Console输出，这里是另一个</STRONG></DIV>
<DIV>Hello World, Chen.Gang<BR>Hello , 陈刚<BR>Hello World, Chen.Gang<BR>Hello , 子在川上曰<BR>&nbsp;</DIV>
<DIV>
<DIV>
<P><STRONG>作者简介</STRONG></P>
<P>陈刚，广西桂林人，著作有《Eclipse从入门到精通》<BR>您可以通过其博客了解更多信息和文章：<A href="http://www.chengang.com.cn/"><FONT color=#000033>http://www.chenGang.com.cn</FONT></A> </P></DIV></DIV>
<DIV></DIV></DIV></DIV><img src ="http://www.blogjava.net/chengang/aggbug/34089.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chengang/" target="_blank">陈刚</a> 2006-03-07 15:17 <a href="http://www.blogjava.net/chengang/archive/2006/03/07/34089.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[JMX一步步来]　7、用JDK5.0的JConsole来连接MBean</title><link>http://www.blogjava.net/chengang/archive/2006/03/07/34088.html</link><dc:creator>陈刚</dc:creator><author>陈刚</author><pubDate>Tue, 07 Mar 2006 07:08:00 GMT</pubDate><guid>http://www.blogjava.net/chengang/archive/2006/03/07/34088.html</guid><wfw:comment>http://www.blogjava.net/chengang/comments/34088.html</wfw:comment><comments>http://www.blogjava.net/chengang/archive/2006/03/07/34088.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/chengang/comments/commentRss/34088.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chengang/services/trackbacks/34088.html</trackback:ping><description><![CDATA[<DIV align=center>文/陈刚&nbsp; from <A href="http://www.chengang.com.cn/">www.chengang.com.cn</A> at 2005-12-26</DIV>
<DIV>　</DIV>
<DIV>　　前面所有看效果都是通过Html网页来看的。JDK5.0自带了一个jmx客户端，叫jconsole，位于c:\jdk\bin\jconsole.exe。我们来用用这个客户端来连接Mbean Server。</DIV>
<DIV>　</DIV>
<DIV><STRONG>一、vm参数方式</STRONG></DIV>
<DIV>　</DIV>
<DIV>1、还是用第一篇的那个HelloAgent，修改HelloAgent，将第一句：</DIV>
<DIV>MBeanServer server = MBeanServerFactory.createMBeanServer();</DIV>
<DIV>改为：<STRONG><FONT color=#ff0000>MBeanServer server = ManagementFactory.getPlatformMBeanServer();</FONT></STRONG></DIV>
<DIV>注：ManagementFactory的全路径为：java.lang.management.ManagementFactory</DIV>
<DIV>　</DIV>
<DIV>2、修改Eclipse的run选项，把<FONT color=#ff0000>“<STRONG>-Dcom.sun.management.jmxremote=HelloAgent</STRONG></FONT>”这一句加入到run选项中，修改如下图：</DIV>
<DIV></DIV>
<DIV><IMG style="DISPLAY: block; MARGIN: 0px auto 10px; TEXT-ALIGN: center" alt=1135579391260_7463.gif src="http://blog.sohu.com/images/person/2005/12/26/1135579391260_7463.gif" border=0></DIV>
<DIV>　</DIV>
<DIV>3、运行HelloAgent，然后在Dos窗口输入“jconsole”来启到JConsole，得到如下界面。<IMG style="DISPLAY: block; MARGIN: 0px auto 10px; TEXT-ALIGN: center" alt=1135579573812_8685.gif src="http://blog.sohu.com/images/person/2005/12/26/1135579573812_8685.gif" border=0>　</DIV>
<DIV>4、单击“连接”，进入以下界面：</DIV>
<DIV><IMG style="DISPLAY: block; MARGIN: 0px auto 10px; TEXT-ALIGN: center" alt=1135579720638_3644.gif src="http://blog.sohu.com/images/person/2005/12/26/1135579720638_3644.gif" border=0></DIV>
<DIV></DIV>
<DIV>　</DIV>
<DIV><STRONG>二、RMI方式</STRONG></DIV>
<DIV><STRONG>　</STRONG></DIV>
<DIV>　　还是用jconsole，但方式变了。这里不需要象上面那样修改Eclipse run的vm选项。</DIV>
<DIV>　</DIV>
<DIV>1、还是用第一篇的HelloAgent，加上一段代码，启动一个JMXConnectorServer服务</DIV>
<DIV>
<DIV></DIV>
<DIV>
<DIV>
<DIV style="BORDER-RIGHT: 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 1px; BORDER-LEFT: 1px solid; WIDTH: 100%; PADDING-TOP: 1px; BORDER-BOTTOM: 1px solid; HEIGHT: 18px"><PRE>import javax.management.MBeanServer;<BR>import javax.management.MBeanServerFactory;<BR>import javax.management.ObjectName;<BR>import javax.management.remote.JMXConnectorServer;<BR>import javax.management.remote.JMXConnectorServerFactory;<BR>import javax.management.remote.JMXServiceURL;</PRE><PRE>import com.sun.jdmk.comm.HtmlAdaptorServer;</PRE><PRE>public class HelloAgent {<BR>&nbsp;&nbsp;&nbsp; public static void main(String args[]) throws Exception {<BR><STRONG><FONT color=#ff0000>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MBeanServer server = MBeanServerFactory.createMBeanServer();<BR></FONT></STRONG>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ObjectName helloName = new ObjectName("chengang:name=HelloWorld");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Hello hello = new Hello();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; server.registerMBean(hello, helloName);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ObjectName adapterName = new ObjectName("HelloAgent:name=htmladapter,port=8082");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HtmlAdaptorServer adapter = new HtmlAdaptorServer();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; server.registerMBean(adapter, adapterName);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adapter.start();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("start.....");</PRE><PRE>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Create an RMI connector and start it<BR><FONT color=#ff0000><STRONG>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/server");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, server);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cs.start();<BR></STRONG></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("rmi　start.....");<BR>&nbsp;&nbsp;&nbsp; }<BR>}</PRE></DIV></DIV>
<DIV>&nbsp;　</DIV>
<DIV>2、在Dos运行一个命令：<STRONG><FONT color=#ff0000>rmiregistry 9999</FONT></STRONG></DIV>
<DIV><STRONG><FONT color=#ff0000></FONT></STRONG>&nbsp;</DIV>
<DIV><FONT color=#000000>3、运行HelloAgent，然后再在dos下运行命令jconsole，得到如下界面，输入</FONT><STRONG><FONT color=#ff0000>service:jmx:rmi:///jndi/rmi://localhost:9999/server</FONT></STRONG></DIV>
<DIV>　<IMG style="DISPLAY: block; MARGIN: 0px auto 10px; TEXT-ALIGN: center" alt=1135580892339_8412.gif src="http://blog.sohu.com/images/person/2005/12/26/1135580892339_8412.gif" border=0></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV><STRONG><FONT color=#ff0000></FONT></STRONG></DIV>
<DIV><STRONG><FONT color=#000000>三、总结</FONT></STRONG></DIV>
<DIV><STRONG></STRONG></DIV>
<DIV><STRONG>　　</STRONG>连接MBeanServer的方式除了Html、JConsole，还有一些第三方的客户端，比较有名的是MC4j，通过这些客户端我们可以很容易去访问MBean。这也就是我们为什么要用JMX的其中一个原因：试想如果我自己搞一套标准，势必要自己开发一个客户端，那会是一个不小的工作量。</DIV>
<DIV>
<DIV>
<P><STRONG>作者简介</STRONG></P>
<P>陈刚，广西桂林人，著作有《Eclipse从入门到精通》<BR>您可以通过其博客了解更多信息和文章：<A href="http://www.chengang.com.cn/"><FONT color=#000033>http://www.chenGang.com.cn</FONT></A> </P></DIV></DIV></DIV></DIV><img src ="http://www.blogjava.net/chengang/aggbug/34088.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chengang/" target="_blank">陈刚</a> 2006-03-07 15:08 <a href="http://www.blogjava.net/chengang/archive/2006/03/07/34088.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[JMX一步步来]　6、模型Bean：Model Bean</title><link>http://www.blogjava.net/chengang/archive/2006/03/07/34087.html</link><dc:creator>陈刚</dc:creator><author>陈刚</author><pubDate>Tue, 07 Mar 2006 07:07:00 GMT</pubDate><guid>http://www.blogjava.net/chengang/archive/2006/03/07/34087.html</guid><wfw:comment>http://www.blogjava.net/chengang/comments/34087.html</wfw:comment><comments>http://www.blogjava.net/chengang/archive/2006/03/07/34087.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/chengang/comments/commentRss/34087.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chengang/services/trackbacks/34087.html</trackback:ping><description><![CDATA[<DIV align=center>文/陈刚&nbsp; from <A href="http://www.chengang.com.cn/">www.chengang.com.cn</A> at 2005-12-26</DIV>
<DIV>　</DIV>
<DIV>　　在上一节是用apache的commons-modeler来开发的一个model，只不过commons-modeler帮助我们实现了很多的代码，而我们只需要写描述XML文件就行了。这一节，来一个实打实的Model Bean，不借助任何第三方工具包。例子还是沿用Hello这个类，以便于和以前的实现相比较。</DIV>
<DIV>　</DIV>
<DIV>一、Model MBean实例</DIV>
<DIV>1、Hello.java还是和以前的一样。这里它没有再加上一个MBean接口了，只是一个很普通的类。</DIV>
<DIV></DIV>
<DIV>
<DIV>
<DIV style="BORDER-RIGHT: 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 1px; BORDER-LEFT: 1px solid; WIDTH: 100%; PADDING-TOP: 1px; BORDER-BOTTOM: 1px solid; HEIGHT: 18px"><PRE>public class Hello{<BR>&nbsp;&nbsp;&nbsp; private String name;<BR>&nbsp;&nbsp;&nbsp; public String getName() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return name;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; public void setName(String name) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.name = name;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; public void printHello() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Hello World, " + name);<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; public void printHello(String whoName) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Hello , " + whoName);<BR>&nbsp;&nbsp;&nbsp; }<BR>}</PRE></DIV></DIV>
<DIV>　</DIV>
<DIV>2、接下来是HelloAgent的写法，和以前就差一句：把“new Hello()”这一句删除了，加上了ModelMbeanUtils.createModlerMbean();</DIV>
<DIV>
<DIV style="BORDER-RIGHT: 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 1px; BORDER-LEFT: 1px solid; WIDTH: 100%; PADDING-TOP: 1px; BORDER-BOTTOM: 1px solid; HEIGHT: 18px"><PRE>import javax.management.MBeanServer;<BR>import javax.management.MBeanServerFactory;<BR>import javax.management.ObjectName;<BR>import javax.management.modelmbean.RequiredModelMBean;</PRE><PRE>import com.sun.jdmk.comm.HtmlAdaptorServer;</PRE><PRE>public class HelloAgent {<BR>&nbsp;&nbsp;&nbsp; public static void main(String[] args) throws Exception {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MBeanServer server = MBeanServerFactory.createMBeanServer();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ObjectName helloName = new ObjectName("chengang:name=HelloWorld");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Hello hello = new Hello();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RequiredModelMBean hello = ModelMBeanUtils.createModlerMBean();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; server.registerMBean(hello, helloName);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ObjectName adapterName = new ObjectName("HelloAgent:name=htmladapter,port=8082");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HtmlAdaptorServer adapter = new HtmlAdaptorServer();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; server.registerMBean(adapter, adapterName);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adapter.start();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("start.....");<BR>&nbsp;&nbsp;&nbsp; }<BR>}</PRE></DIV></DIV>
<DIV>&nbsp;</DIV>
<DIV>3、ModelMbeanUtils这个类是要我们自己来实现的，也是写model Bean最麻烦的地方，它主要是返回一个RequiredModelMBean类，此类主要包括了一个ModelMBeanInfo类的信息。在ModelMBeanInfo中定义了所有对需要管理的属性和方法的描述。具体代码如下：</DIV>
<DIV>
<DIV style="BORDER-RIGHT: 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 1px; BORDER-LEFT: 1px solid; WIDTH: 100%; PADDING-TOP: 1px; BORDER-BOTTOM: 1px solid; HEIGHT: 18px">
<DIV>import javax.management.MBeanParameterInfo;<BR>import javax.management.modelmbean.ModelMBeanAttributeInfo;<BR>import javax.management.modelmbean.ModelMBeanInfo;<BR>import javax.management.modelmbean.ModelMBeanInfoSupport;<BR>import javax.management.modelmbean.ModelMBeanOperationInfo;<BR>import javax.management.modelmbean.RequiredModelMBean;</DIV>
<DIV></DIV>
<DIV>public class ModelMBeanUtils {<BR>&nbsp;&nbsp;&nbsp; private static final boolean READABLE = true;<BR>&nbsp;&nbsp;&nbsp; private static final boolean WRITABLE = true;<BR>&nbsp;&nbsp;&nbsp; private static final boolean BOOLEAN = true;<BR>&nbsp;&nbsp;&nbsp; private static final String STRING_CLASS = "java.lang.String";</DIV>
<DIV></DIV>
<DIV>&nbsp;&nbsp;&nbsp; public static RequiredModelMBean createModlerMBean() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RequiredModelMBean model = null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; model = new RequiredModelMBean();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; model.setManagedResource(new Hello(), "ObjectReference");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ModelMBeanInfo info = createModelMBeanInfo();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; model.setModelMBeanInfo(info);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (Exception e) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return model;<BR>&nbsp;&nbsp;&nbsp; }</DIV>
<DIV></DIV>
<DIV>&nbsp;&nbsp;&nbsp; private static ModelMBeanInfo createModelMBeanInfo() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //////////////////////////////////////////////////////////////////<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 属性&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //////////////////////////////////////////////////////////////////<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 构造name属性信息<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ModelMBeanAttributeInfo nameAttrInfo = new ModelMBeanAttributeInfo(//<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Name", // 属性名&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; STRING_CLASS, //属性类型&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "people name", // 描述文字&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; READABLE, WRITABLE, !BOOLEAN, // 读写&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null // 属性描述子<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );</DIV>
<DIV></DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //////////////////////////////////////////////////////////////////<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 方法&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //////////////////////////////////////////////////////////////////<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //构造 printHello()操作的信息&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ModelMBeanOperationInfo print1Info = new ModelMBeanOperationInfo(//<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "printHello", //<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null, //&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null, //<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "void", //&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MBeanOperationInfo.INFO, //&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null //<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );</DIV>
<DIV></DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 构造printHello(String whoName)操作信息&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ModelMBeanOperationInfo print2Info;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MBeanParameterInfo[] param2 = new MBeanParameterInfo[1];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; param2[0] = new MBeanParameterInfo("whoName", STRING_CLASS, "say hello to who");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print2Info = new ModelMBeanOperationInfo(//<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "printHello", //<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null,//<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; param2,//<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "void", //<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MBeanOperationInfo.INFO, //<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null//<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );</DIV>
<DIV></DIV>
<DIV>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //////////////////////////////////////////////////////////////////<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 最后总合&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //////////////////////////////////////////////////////////////////<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // create ModelMBeanInfo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ModelMBeanInfo mbeanInfo = new ModelMBeanInfoSupport(//<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RequiredModelMBean.class.getName(), // MBean类<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null, // 描述文字&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new ModelMBeanAttributeInfo[] { // 所有的属性信息（数组） <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nameAttrInfo },//只有一个属性 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null, // 所有的构造函数信息&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new ModelMBeanOperationInfo[] { // 所有的操作信息（数组）<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print1Info,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print2Info },//<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null, // 所有的通知信息(本例无)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null//MBean描述子<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; );<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return mbeanInfo;<BR>&nbsp;&nbsp;&nbsp; }<BR>}</DIV></DIV></DIV>
<DIV>&nbsp;</DIV>
<DIV>4、看效果的方法和以前一样，运行HelloAgent，用浏览器打开：<A href="http://localhost:8082/">http://localhost:8082</A> 。效果图和standard mbean一样，就不再帖出来了，去第一篇去看吧<A href="http://blog.sohu.com/members/somebody076/545896.html">http://blog.sohu.com/members/somebody076/545896.html</A></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV>&nbsp;</DIV>
<DIV>二、总结</DIV>
<DIV>　</DIV>
<DIV>&nbsp;&nbsp; 我们发现模型Mbean(Model MBean)要比标准MBean(standard mbean)复杂多了，那有什么理由让我们选择使用模型MBean吗？我认为，最大的理由就是模型MBean可以动态配置。试想一下这个应用场景：由于安全或其他原因，系统要把某个MBean公开的可管理方法隐藏起来。这时，如果你是用标准MBean，这需要修改接口类，然后重新编译发布；如果用Apache commons-modeler来写的模型MBean，则只需要修改XML文件就行了，不需要重新编译发布（可能要重启一下系统）。这就是模型Mbean优势之所在了。</DIV>
<DIV>　</DIV>
<DIV>　细心的人会发现动态MBean和这一节的模型Mbean非常相似，但它们还是有很大不同的：动态MBean没有Hello类，它要自己实现Hello类中的方法逻辑。</DIV>
<DIV>　　　</DIV>
<DIV>
<P><STRONG>作者简介</STRONG></P>
<P>陈刚，广西桂林人，著作有《Eclipse从入门到精通》<BR>您可以通过其博客了解更多信息和文章：<A href="http://www.chengang.com.cn/"><FONT color=#000033>http://www.chenGang.com.cn</FONT></A> </P></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV></DIV></DIV><img src ="http://www.blogjava.net/chengang/aggbug/34087.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chengang/" target="_blank">陈刚</a> 2006-03-07 15:07 <a href="http://www.blogjava.net/chengang/archive/2006/03/07/34087.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[JMX一步步来]　5、用Apache的commons-modeler来辅助开发JMX</title><link>http://www.blogjava.net/chengang/archive/2006/03/07/34086.html</link><dc:creator>陈刚</dc:creator><author>陈刚</author><pubDate>Tue, 07 Mar 2006 07:05:00 GMT</pubDate><guid>http://www.blogjava.net/chengang/archive/2006/03/07/34086.html</guid><wfw:comment>http://www.blogjava.net/chengang/comments/34086.html</wfw:comment><comments>http://www.blogjava.net/chengang/archive/2006/03/07/34086.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/chengang/comments/commentRss/34086.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chengang/services/trackbacks/34086.html</trackback:ping><description><![CDATA[<DIV align=center>文/陈刚&nbsp; from <A href="http://www.chengang.com.cn/">www.chengang.com.cn</A> at 2005-12-13</DIV>
<DIV>&nbsp;</DIV>
<DIV><STRONG>一、前言</STRONG></DIV>
<DIV>　</DIV>
<DIV>　　每一个MBean都要有一个接口，比如前面的Hello要有一个HelloMBean接口。要多维护一个接口，的确是件麻烦的事。Apache的commons-modeler利用JMX中的动态MBean原理很好的解决了这一问题，commons-modeler使用得我们可以只写Hello，而不用写HelloMBean这个接口。不过这是有代价的，它要求我们写一个mbean的xml描述文件（唉，少了一件事，却又多出另一件事来）。但commons-modeler还是有优点的，就是它让mbean的装配更加灵活，把多个mbean的装配都集中在一个XML文件里来了。</DIV>
<DIV></DIV>
<DIV>　　开始实例之前，你需要先去apache网站下载commons-modeler，以及modeler的依赖项目commons-logging。下载网址为：<A href="http://jakarta.apache.org/site/downloads/downloads_commons.html">http://jakarta.apache.org/site/downloads/downloads_commons.html</A>，下载的文件是ZIP压缩包，解压后找到commons-logging.jar和commons-modeler.jar。如果在DOS下用命令行开发，则把这两个JAR包加入到classpath系统变量中。如果你用Eclipse开发，则把JAR包加入到项目属性的Libratries（库）引用中。<BR></DIV>
<DIV>&nbsp;</DIV>
<DIV><STRONG>二、HelloWorld实例</STRONG></DIV>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;　我们以本系统的第一篇“1、JMX的Hello World”为例，来重新实现一次。</DIV>
<DIV>　</DIV>
<DIV>1、Hello.java的代码不变（注：为了在Eclipse上和原来的Hello文件放在不同的地方，我把新Hello放到了mbean.modelbean包），如下：</DIV>
<DIV>
<DIV style="BORDER-RIGHT: 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 1px; BORDER-LEFT: 1px solid; WIDTH: 100%; PADDING-TOP: 1px; BORDER-BOTTOM: 1px solid; HEIGHT: 18px"><PRE>package mbean.modelbean;</PRE><PRE>import mbean.standard.HelloMBean;</PRE><PRE>public class Hello implements HelloMBean {<BR>&nbsp;&nbsp;&nbsp; private String name;<BR>&nbsp;&nbsp;&nbsp; public String getName() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return name;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; public void setName(String name) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.name = name;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; public void printHello() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Hello World, " + name);<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; public void printHello(String whoName) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Hello , " + whoName);<BR>&nbsp;&nbsp;&nbsp; }<BR>}</PRE></DIV></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV>&nbsp;</DIV>
<DIV>2、MBean不用写了，但需要写一个XML描述文件。文件名任取，这里取名为：mbeans-descriptors</DIV>
<DIV>
<DIV style="BORDER-RIGHT: 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 1px; BORDER-LEFT: 1px solid; WIDTH: 100%; PADDING-TOP: 1px; BORDER-BOTTOM: 1px solid; HEIGHT: 18px"><PRE>&lt;?xml version="1.0"?&gt;<BR>&lt;mbeans-descriptors&gt;<BR>&nbsp;&lt;mbean name="Hello" description="the hello bean" domain="chengang" group="helloGroup" type="mbean.modelbean.Hello"&gt;<BR>&nbsp;&nbsp;&lt;attribute name="name" description="a name attribute" type="java.lang.String" writeable="true"/&gt;<BR>&nbsp;&nbsp;&lt;operation name="printHello" description="a operation to print hello" impact="INFO" returnType="String"/&gt;<BR>&nbsp;&lt;/mbean&gt;<BR>&lt;/mbeans-descriptors&gt;&nbsp;</PRE></DIV></DIV>
<DIV></DIV>
<DIV>这里只对&lt;mbean&gt;标签做一下说明：</DIV>
<UL>
<LI>name mbean在xml中的唯一标识，不一定要和类同名 
<LI>description　mbean的注释说明信息 
<LI>domain mbean所属域 
<LI>group mbean所属组 
<LI>type mbean的类全名（包名＋类名） 
<LI>classname 指定实现代理功能的ModelMbean的全名，如果不指定则默认为BaseModelMBean&nbsp;</LI></UL>
<DIV>3、接下来改写HelloAgent</DIV>
<DIV></DIV>
<DIV>
<DIV style="BORDER-RIGHT: 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 1px; BORDER-LEFT: 1px solid; WIDTH: 100%; PADDING-TOP: 1px; BORDER-BOTTOM: 1px solid; HEIGHT: 18px"><PRE>package mbean.modelbean;</PRE><PRE>import java.io.InputStream;<BR>import javax.management.MBeanServer;<BR>import javax.management.ObjectName;<BR>import javax.management.modelmbean.ModelMBean;<BR>import org.apache.commons.modeler.ManagedBean;<BR>import org.apache.commons.modeler.Registry;<BR>import com.sun.jdmk.comm.HtmlAdaptorServer;</PRE><PRE>public class HelloAgent {<BR>&nbsp;&nbsp;&nbsp; public static void main(String[] args) throws Exception {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //基于xml中的信息构建一个Registry<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Registry registry = Registry.getRegistry(null, null);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InputStream stream = HelloAgent.class.getResourceAsStream("Mbeans-descriptors.xml");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; registry.loadMetadata(stream);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stream.close();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //由Registry得到一个MBeanServer<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MBeanServer server = registry.getMBeanServer();</PRE><PRE>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //得到Hello在描述文件中的信息类，对应于xml文件&lt;mbean&gt;标签的name属性。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ManagedBean managed = registry.findManagedBean("Hello");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //创建ObjectName<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ObjectName helloName = new ObjectName(managed.getDomain() + ":name=HelloWorld");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //得到ModelMBean<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ModelMBean hello = managed.createMBean(new Hello());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //注册MBean<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; server.registerMBean(hello, helloName);</PRE><PRE>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ObjectName adapterName = new ObjectName("HelloAgent:name=htmladapter,port=8082");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HtmlAdaptorServer adapter = new HtmlAdaptorServer();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; server.registerMBean(adapter, adapterName);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adapter.start();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("start.....");<BR>&nbsp;&nbsp;&nbsp; }<BR>}</PRE></DIV></DIV>
<DIV></DIV>
<DIV>　</DIV>
<DIV>HelloAgent是效复杂的地方，我们来和以前的HelloAgent逐步比较一下，前后有什么不同：</DIV>
<DIV></DIV>
<DIV>（1）首先，新的HelloAgent需要将xml信息读入到Registry对象中，这是旧HelloAgent所没有的。</DIV>
<DIV>
<DIV style="BORDER-RIGHT: 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 1px; BORDER-LEFT: 1px solid; WIDTH: 100%; PADDING-TOP: 1px; BORDER-BOTTOM: 1px solid; HEIGHT: 18px"><PRE>Registry registry = Registry.getRegistry(null, null);<BR>InputStream stream = HelloAgent.class.getResourceAsStream("Mbeans-descriptors.xml");<BR>registry.loadMetadata(stream);<BR>stream.close();</PRE></DIV></DIV>
<DIV>&nbsp;</DIV>
<DIV>（2）接着创建MBeanServer的方式也不同了</DIV>
<DIV>
<DIV>现在：MBeanServer server = registry.getMBeanServer();</DIV></DIV>
<DIV>以前: MBeanServer server = MBeanServerFactory.createMBeanServer();</DIV>
<DIV>　</DIV>
<DIV>（3）Hello相应的ObjectName创建也略不相同。主要是域名在XML描述文件里设置好了。</DIV>
<DIV>现在：ManagedBean managed = registry.findManagedBean("Hello");<BR>&nbsp;&nbsp;&nbsp;&nbsp; ObjectName helloName = new ObjectName(managed.getDomain() + ":name=HelloWorld");<BR>以前：ObjectName helloName = new ObjectName("chengang:name=HelloWorld")</DIV>
<DIV>　</DIV>
<DIV>（4）得到MBean的方式也不同，这里就是关键的不同点</DIV>
<DIV>现在：ModelMBean hello = managed.createMBean(new Hello());</DIV>
<DIV>以前：Hello hello = new Hello();</DIV>
<DIV>注意：为什么现在要比以前多一个createMbean步骤呢，就是因为现在的写法并没有写Mbean，所以需要动态才需要生成一个。而以前就直接把new Hello()注册到mbean server就可以了，server会自动找到它的HelloMBean接口文件。</DIV>
<DIV>　</DIV>
<DIV>　也就上面四点区别，其他代码完全一样。测试和查看效果的方法和以前一样，在此不累述了。我们来看看界面情况有那些变化（红圈部份）。</DIV>
<DIV></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV><IMG style="DISPLAY: block" alt=1134441073198_3333.gif src="http://blog.sohu.com/images/person/2005/12/13/1134441073198_3333.gif" border=0></DIV>
<DIV>　</DIV>
<DIV>　由图可见commons Modeler为Hello动态生成了一个MBean接口：BaseModelBean</DIV>
<DIV>　</DIV>
<DIV><STRONG>参考资料</STRONG></DIV>
<DIV>　　<A HREF="/blogjava_zcx/archive/2005/01/11/217.html">用Commons Modeler 开发JMX应用</A></DIV>
<DIV></DIV>
<DIV>
<DIV>
<P><STRONG>作者简介</STRONG></P>
<P>陈刚，广西桂林人，著作有《Eclipse从入门到精通》<BR>您可以通过其博客了解更多信息和文章：<A href="http://www.chengang.com.cn/"><FONT color=#000033>http://www.chenGang.com.cn</FONT></A> </P></DIV></DIV><img src ="http://www.blogjava.net/chengang/aggbug/34086.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chengang/" target="_blank">陈刚</a> 2006-03-07 15:05 <a href="http://www.blogjava.net/chengang/archive/2006/03/07/34086.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[JMX一步步来]　4、动态MBean：DynamicMBean</title><link>http://www.blogjava.net/chengang/archive/2006/03/07/34084.html</link><dc:creator>陈刚</dc:creator><author>陈刚</author><pubDate>Tue, 07 Mar 2006 07:03:00 GMT</pubDate><guid>http://www.blogjava.net/chengang/archive/2006/03/07/34084.html</guid><wfw:comment>http://www.blogjava.net/chengang/comments/34084.html</wfw:comment><comments>http://www.blogjava.net/chengang/archive/2006/03/07/34084.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/chengang/comments/commentRss/34084.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chengang/services/trackbacks/34084.html</trackback:ping><description><![CDATA[<DIV align=center>文/陈刚&nbsp; from <A href="http://www.chengang.com.cn/">www.chengang.com.cn</A> at 2005-12-4</DIV>
<DIV align=center>&nbsp;　</DIV>
<DIV></DIV>
<DIV><STRONG>一、前言</STRONG></DIV>
<DIV>　</DIV>
<DIV>　　动态MBean是在运行期才定义它的属性和方法，也就是说它有什么属性和方法是可以动态改变的。动态MBean主要利用一些辅助类（构造函数类MBeanConstructorInfo、属性类MBeanAttributeInfo、方法类MBeanOperationInfo）来完成这个功能，所有的动态MBean必须实现DynamicMBean接口。DynamicMBean写好后，使用方法和第一篇文章中普通的MBean一样。</DIV>
<DIV>　</DIV>
<DIV>　　给出一个动态MBean的实例，这个实例最初动态构了一个Name属性及一个print方法，当我们执行它的print方法之后，又给此MBean新增了一个print1方法。实例的代码如下：</DIV>
<DIV></DIV>
<DIV></DIV>
<DIV><STRONG>二、实例</STRONG></DIV>
<DIV></DIV>
<DIV>1、HelloDynamic类</DIV>
<DIV></DIV>
<DIV>
<DIV style="BORDER-RIGHT: 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 1px; BORDER-LEFT: 1px solid; WIDTH: 100%; PADDING-TOP: 1px; BORDER-BOTTOM: 1px solid; HEIGHT: 18px"><PRE>import java.lang.reflect.Constructor;<BR>import java.util.Iterator;<BR>import javax.management.Attribute;<BR>import javax.management.AttributeList;<BR>import javax.management.DynamicMBean;<BR>import javax.management.MBeanAttributeInfo;<BR>import javax.management.MBeanConstructorInfo;<BR>import javax.management.MBeanException;<BR>import javax.management.MBeanInfo;<BR>import javax.management.MBeanNotificationInfo;<BR>import javax.management.MBeanOperationInfo;<BR>import javax.management.MBeanParameterInfo;<BR>import javax.management.ReflectionException;</PRE><PRE>/**<BR>&nbsp;* @author Sunny Peng<BR>&nbsp;* @author change by Chen.Gang, add a feature for dynamic add operation<BR>&nbsp;* @version 1.0<BR>&nbsp;*/<BR>public class HelloDynamic implements DynamicMBean {<BR>&nbsp;&nbsp;&nbsp; //这是我们的属性名称<BR>&nbsp;&nbsp;&nbsp; private String name;<BR>&nbsp;&nbsp;&nbsp; private MBeanInfo mBeanInfo = null;<BR>&nbsp;&nbsp;&nbsp; private String className;<BR>&nbsp;&nbsp;&nbsp; private String description;<BR>&nbsp;&nbsp;&nbsp; private MBeanAttributeInfo[] attributes;<BR>&nbsp;&nbsp;&nbsp; private MBeanConstructorInfo[] constructors;<BR>&nbsp;&nbsp;&nbsp; private MBeanOperationInfo[] operations;<BR>&nbsp;&nbsp;&nbsp; MBeanNotificationInfo[] mBeanNotificationInfoArray;</PRE><PRE>&nbsp;&nbsp;&nbsp; public HelloDynamic() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; init();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buildDynamicMBean();<BR>&nbsp;&nbsp;&nbsp; }</PRE><PRE>&nbsp;&nbsp;&nbsp; private void init() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; className = this.getClass().getName();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; description = "Simple implementation of a dynamic MBean.";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; attributes = new MBeanAttributeInfo[1];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; constructors = new MBeanConstructorInfo[1];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; operations = new MBeanOperationInfo[1];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mBeanNotificationInfoArray = new MBeanNotificationInfo[0];<BR>&nbsp;&nbsp;&nbsp; }</PRE><PRE>&nbsp;&nbsp;&nbsp; private void buildDynamicMBean() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //设定构造函数<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Constructor[] thisconstructors = this.getClass().getConstructors();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; constructors[0] = new MBeanConstructorInfo("HelloDynamic(): Constructs a HelloDynamic object", thisconstructors[0]);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //设定一个属性<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; attributes[0] = new MBeanAttributeInfo("Name", "java.lang.String", "Name: name string.", true, true, false);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //operate method 我们的操作方法是print<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MBeanParameterInfo[] params = null;//无参数<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; operations[0] = new MBeanOperationInfo("print", "print(): print the name", params, "void", MBeanOperationInfo.INFO);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mBeanInfo = new MBeanInfo(className, description, attributes, constructors, operations, mBeanNotificationInfoArray);<BR>&nbsp;&nbsp;&nbsp; }</PRE><PRE>&nbsp;&nbsp;&nbsp; //动态增加一个print1方法<BR>&nbsp;&nbsp;&nbsp; private void dynamicAddOperation() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; init();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; operations = new MBeanOperationInfo[2];//设定数组为两个<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buildDynamicMBean();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; operations[1] = new MBeanOperationInfo("print1", "print1(): print the name", null, "void", MBeanOperationInfo.INFO);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mBeanInfo = new MBeanInfo(className, description, attributes, constructors, operations, mBeanNotificationInfoArray);<BR>&nbsp;&nbsp;&nbsp; }</PRE><PRE>&nbsp;&nbsp;&nbsp; public Object getAttribute(String attribute_name) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (attribute_name != null)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (attribute_name.equals("Name"))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return name;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return null;<BR>&nbsp;&nbsp;&nbsp; }</PRE><PRE>&nbsp;&nbsp;&nbsp; public void setAttribute(Attribute attribute) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (attribute == null)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String Name = attribute.getName();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object value = attribute.getValue();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (Name.equals("Name")) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // if null value, try and see if the setter returns any exception<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (value == null) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name = null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // if non null value, make sure it is assignable to the attribute<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if ((Class.forName("java.lang.String")).isAssignableFrom(value.getClass())) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name = (String) value;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (Exception e) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }</PRE><PRE>&nbsp;&nbsp;&nbsp; public AttributeList getAttributes(String[] attributeNames) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (attributeNames == null)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AttributeList resultList = new AttributeList();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // if attributeNames is empty, return an empty result list<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (attributeNames.length == 0)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return resultList;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; attributeNames.length; i++) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object value = getAttribute(attributeNames[i]);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; resultList.add(new Attribute(attributeNames[i], value));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (Exception e) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return resultList;<BR>&nbsp;&nbsp;&nbsp; }</PRE><PRE>&nbsp;&nbsp;&nbsp; public AttributeList setAttributes(AttributeList attributes) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (attributes == null)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AttributeList resultList = new AttributeList();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // if attributeNames is empty, nothing more to do<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (attributes.isEmpty())<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return resultList;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // for each attribute, try to set it and add to the result list if successfull<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (Iterator i = attributes.iterator(); i.hasNext();) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Attribute attr = (Attribute) i.next();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setAttribute(attr);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String name = attr.getName();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object value = getAttribute(name);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; resultList.add(new Attribute(name, value));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (Exception e) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return resultList;<BR>&nbsp;&nbsp;&nbsp; }</PRE><PRE>&nbsp;&nbsp;&nbsp; public Object invoke(String operationName, Object params[], String signature[]) throws MBeanException, ReflectionException {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Check for a recognized operation name and call the corresponding operation<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (operationName.equals("print")) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //具体实现我们的操作方法print <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Hello, " + name + ", this is HellDynamic!");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dynamicAddOperation();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (operationName.equals("print1")) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("这是动态增加的一方法print1");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return null;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // unrecognized operation name:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new ReflectionException(new NoSuchMethodException(operationName), "Cannot find the operation " + operationName + " in " + className);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</PRE><PRE>&nbsp;&nbsp;&nbsp; }</PRE><PRE>&nbsp;&nbsp;&nbsp; public MBeanInfo getMBeanInfo() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return mBeanInfo;<BR>&nbsp;&nbsp;&nbsp; }<BR>}</PRE></DIV></DIV>
<DIV>&nbsp;</DIV>
<DIV>说明：</DIV>
<UL>
<LI>实现于接口DynamicMBean 
<LI>借助于各种辅助类完成一个类的构造。构造函数类MBeanConstructorInfo、属性类MBeanAttributeInfo、方法类MBeanOperationInfo 
<LI>这里所有public方法是实现于DynamicMBean的。主要提供：setAttribute设置属性、getAttribute取得属性、setAttributes设置一组属性、getAttributes取得一组属性、invoke方法调用、getMBeanInfo　MBeanServer由这个方法得到关键的MBean类的构造信息。</LI></UL>
<DIV>2、HelloAgent类</DIV>
<DIV>　　</DIV>
<DIV>　　前面说了HelloDynamic和普通MBean的使用方法是一样的，因此HelloAgent和第一篇的HelloAgent基本一样，就是把Hello改成HelloDynamic而已。为了实例完整，也一并帖出来吧。</DIV>
<DIV>
<DIV style="BORDER-RIGHT: 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 1px; BORDER-LEFT: 1px solid; WIDTH: 100%; PADDING-TOP: 1px; BORDER-BOTTOM: 1px solid; HEIGHT: 18px"><PRE>import javax.management.MBeanServerFactory;<BR>import javax.management.ObjectName;<BR>import com.sun.jdmk.comm.HtmlAdaptorServer;<BR>public class HelloAgent {<BR>&nbsp;&nbsp;&nbsp; public static void main(String[] args) throws Exception {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MBeanServer server = MBeanServerFactory.createMBeanServer();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ObjectName helloName = new ObjectName("chengang:name=HelloDynamic");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HelloDynamic hello = new HelloDynamic();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; server.registerMBean(hello, helloName);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ObjectName adapterName = new ObjectName("HelloAgent:name=htmladapter,port=8082");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HtmlAdaptorServer adapter = new HtmlAdaptorServer();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; server.registerMBean(adapter, adapterName);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adapter.start();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("start.....");<BR>&nbsp;&nbsp;&nbsp; }<BR>}</PRE></DIV></DIV>
<DIV>　</DIV>
<DIV><STRONG>3、运行</STRONG></DIV>
<DIV>　</DIV>
<DIV>　　先运行HelloAgent。再打开浏览器，输入网址：<A href="http://localhost:8082/">http://localhost:8082/</A>。单击进入“<A href="http://localhost:8082/ViewObjectRes//chengang:name=HelloDynamic">name=HelloDynamic</A> ”项，执行print方法后再回到上一页面你会发现又多了一个print1方法。</DIV>
<DIV>　</DIV>
<DIV><STRONG>4、总结</STRONG></DIV>
<DIV><STRONG></STRONG></DIV>
<DIV><STRONG>　　</STRONG>动态MBean的代码稍显复杂，但对于一些特殊需求的情况，它将显示出强大威力。而且它还是模型MBeans（Model MBeans）的基础。不过在一般的项目中，动态MBean还是用得比较少，所谓利器深藏之而不用，非常时方现光芒。</DIV>
<DIV>
<P><STRONG>作者简介</STRONG></P>
<P>陈刚，广西桂林人，著作有《Eclipse从入门到精通》<BR>您可以通过其博客了解更多信息和文章：<A href="http://www.chengang.com.cn/"><FONT color=#000033>http://www.chenGang.com.cn</FONT></A> </P></DIV><img src ="http://www.blogjava.net/chengang/aggbug/34084.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chengang/" target="_blank">陈刚</a> 2006-03-07 15:03 <a href="http://www.blogjava.net/chengang/archive/2006/03/07/34084.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[JMX一步步来]　3、Notification的使用</title><link>http://www.blogjava.net/chengang/archive/2006/03/07/34083.html</link><dc:creator>陈刚</dc:creator><author>陈刚</author><pubDate>Tue, 07 Mar 2006 07:01:00 GMT</pubDate><guid>http://www.blogjava.net/chengang/archive/2006/03/07/34083.html</guid><wfw:comment>http://www.blogjava.net/chengang/comments/34083.html</wfw:comment><comments>http://www.blogjava.net/chengang/archive/2006/03/07/34083.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/chengang/comments/commentRss/34083.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chengang/services/trackbacks/34083.html</trackback:ping><description><![CDATA[<DIV>
<DIV align=center>文/陈刚 from <A href="http://www.chengang.com.cn/">www.chengang.com.cn</A> at 2005-12-4</DIV>
<DIV align=center>　</DIV>
<DIV align=center></DIV>
<DIV></DIV>
<DIV><STRONG>一、简介</STRONG></DIV>
<DIV>　</DIV>
<DIV></DIV>
<DIV>　　Mbean之间的通信是必不可少的，Notification就起到了在Mbean之间沟通桥梁的作用。JMX notification 由四部分组成：</DIV>
<DIV></DIV>
<UL>
<LI>Notification 这个相当于一个信息包，封装了需要传递的信息 
<LI>Notification broadcaster　这相当于一个广播器，把消息广播出去 
<LI>Notification listerner　这是一个监听器，用于监听广播出来的Notification消息 
<LI>Notification filter　这是一个过滤器，过滤掉不需要的Notification消息</LI></UL>
<DIV></DIV>
<DIV>　&nbsp;Notification broadcaster不需要我们实现，JMX的内部已经有了。Notification filter一般也很少用。下面的例子主要用到了Notification、Notification listerner。</DIV>
<DIV></DIV>
<DIV><BR></DIV>
<DIV><STRONG>二、实例</STRONG></DIV>
<DIV>　</DIV>
<DIV></DIV>
<DIV>　　在第一篇的Hello中有一个printHello(String whoName)方法，意思根据碰到的是谁来打招呼，比如：</DIV>
<DIV>&nbsp;　</DIV>
<DIV>　　Jack从对面走过来，说：“hi”</DIV>
<DIV>　　我们回之以礼，说：“Hello, jack”</DIV>
<DIV>　</DIV>
<DIV></DIV>
<DIV>　　首先这需要Jack先说一个hi（相应一个操作方法），然后他说的话封装成声波（相当Notification消息包）传递出去。然后我们还要给Jakc装上一个监听器（Hello的耳朵？？^_^），这个监听器将捕捉到Jack的声波语音包，并进行相应处理，即说“Hello, jack”。</DIV>
<DIV>　</DIV>
<DIV></DIV>
<DIV>　　好，我们看看如何实现的：</DIV>
<DIV>　</DIV>
<DIV>1、Jack类及其相应的MBean</DIV>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;&nbsp;&nbsp;我们把Jack写成一个MBean，如下：&nbsp;</DIV>
<DIV></DIV>
<DIV>
<DIV style="BORDER-RIGHT: 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 1px; BORDER-LEFT: 1px solid; WIDTH: 100%; PADDING-TOP: 1px; BORDER-BOTTOM: 1px solid; HEIGHT: 18px"><PRE>import javax.management.Notification;<BR>import javax.management.NotificationBroadcasterSupport;</PRE><PRE>public class Jack extends NotificationBroadcasterSupport implements JackMBean {<BR>&nbsp;&nbsp;&nbsp; private int seq = 0;<BR>&nbsp;&nbsp;&nbsp; public void hi() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Notification n = new Notification(//创建一个信息包<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "jack.hi",//给这个Notification起个名称<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this, //由谁发出的Notification<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ++seq,//一系列通知中的序列号,可以设任意数值<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.currentTimeMillis(),//发出时间<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Jack");//发出的消息文本<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //发出去<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sendNotification(n);<BR>&nbsp;&nbsp;&nbsp; }<BR>}</PRE></DIV></DIV>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;说明： </DIV>
<UL>
<LI>必需继承NotificationBroadcasterSupport 
<LI>此类只有一个hi方法，方法只有两句：创建一个Notification消息包，然后将包发出去 
<LI>如果你还要在消息包上附加其他数据，Notification还有一个setUserData方法可供使用</LI></UL>
<DIV></DIV>
<DIV>
<DIV>
<DIV>2、接下来是他的MBean&nbsp;</DIV></DIV>
<DIV>
<DIV>
<DIV>
<DIV style="BORDER-RIGHT: 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 1px; BORDER-LEFT: 1px solid; WIDTH: 100%; PADDING-TOP: 1px; BORDER-BOTTOM: 1px solid; HEIGHT: 18px"><PRE>public interface JackMBean {<BR>&nbsp;&nbsp;&nbsp; public void hi();<BR>}</PRE></DIV></DIV>
<DIV>&nbsp;</DIV>
<DIV>3、创建一个Listener，监听到的Notification消息包将由此类负责处理。</DIV></DIV>
<DIV>&nbsp; 
<DIV>
<DIV style="BORDER-RIGHT: 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 1px; BORDER-LEFT: 1px solid; WIDTH: 100%; PADDING-TOP: 1px; BORDER-BOTTOM: 1px solid; HEIGHT: 18px"><PRE>import javax.management.Notification;<BR>import javax.management.NotificationListener;<BR>public class HelloListener implements NotificationListener {<BR>&nbsp;&nbsp;&nbsp; public void handleNotification(Notification n, Object handback) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("type=" + n.getType());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("source=" + n.getSource());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("seq=" + n.getSequenceNumber());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("send time=" + n.getTimeStamp());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("message=" + n.getMessage());</PRE><PRE>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (handback != null) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (handback instanceof Hello) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Hello hello = (Hello) handback;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hello.printHello(n.getMessage());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR>}</PRE></DIV></DIV>
<DIV>&nbsp;</DIV>
<DIV>
<DIV>4、修改HelloAgent如下（加上了红色的三句）：</DIV>
<DIV></DIV>
<DIV>
<DIV style="BORDER-RIGHT: 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 1px; BORDER-LEFT: 1px solid; WIDTH: 100%; PADDING-TOP: 1px; BORDER-BOTTOM: 1px solid; HEIGHT: 18px"><PRE>import javax.management.MBeanServer;<BR>import javax.management.MBeanServerFactory;<BR>import javax.management.ObjectName;<BR>import com.sun.jdmk.comm.HtmlAdaptorServer;<BR>public class HelloAgent {<BR>&nbsp;&nbsp;&nbsp; public static void main(String args[]) throws Exception{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MBeanServer server = MBeanServerFactory.createMBeanServer();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ObjectName helloName = new ObjectName("chengang:name=HelloWorld");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Hello hello=new Hello();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; server.registerMBean(hello, helloName);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ObjectName adapterName = new ObjectName("HelloAgent:name=htmladapter,port=8082");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HtmlAdaptorServer adapter = new HtmlAdaptorServer();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; server.registerMBean(adapter, adapterName);<BR><FONT color=#ff0000>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Jack jack = new Jack();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; server.registerMBean(jack, new ObjectName("HelloAgent:name=jack"));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jack.addNotificationListener(new HelloListener(), null, hello);<BR></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adapter.start();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("start.....");<BR>&nbsp;&nbsp;&nbsp; }<BR>}</PRE></DIV></DIV>
<DIV>&nbsp;</DIV>
<DIV></DIV>
<DIV><STRONG>三、运行</STRONG><STRONG>&nbsp;</STRONG></DIV>
<DIV></DIV>
<DIV>1、先运行HelloAgent启动服务，再打开浏览器输入网址：<A href="http://localhost:8082/">http://localhost:8082/</A>，出现如下界面。<IMG style="DISPLAY: block" alt=1133701664014_6541.jpg src="http://blog.sohu.com/images/person/2005/12/4/1133701664014_6541.jpg" border=0></DIV>
<DIV></DIV>
<DIV>&nbsp;</DIV>
<DIV>2、　进入“name=jack”项，然后单击“hi”按钮来执行它。这时Eclipse的console视图显示如下：</DIV>
<DIV>　</DIV>
<DIV><IMG style="DISPLAY: block" alt=1133702044916_7117.jpg src="http://blog.sohu.com/images/person/2005/12/4/1133702044916_7117.jpg" border=0></DIV>
<DIV></DIV>
<DIV>
<DIV></DIV></DIV></DIV></DIV></DIV></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV>
<P><STRONG>四、总结</STRONG></P>
<P><STRONG>　　</STRONG>Notification和Java的事件模型是一样的，另外如果你买了《Eclipse从入门到精通》，你会发现第22.4节也使用了和Notification和Java的事件模型相同的设计方式。Notification在我们的实际项目中也用到了，象我们现在的给移动做的项目中（基于JMX实现)，分散在各地方的工作站的日志，就是通过Notification方式，把每条产生的日志封装在Notification中实时发回主控服务器的。有机会我会发这一系统的关于日志的设计方案写一下，它实现了对各地工作站的集中的、实时的监控，非常实用。</P>
<P><STRONG>作者简介</STRONG></P>
<P>陈刚，广西桂林人，著作有《Eclipse从入门到精通》<BR>您可以通过其博客了解更多信息和文章：<A href="http://www.chengang.com.cn/"><FONT color=#000033>http://www.chenGang.com.cn</FONT></A> </P></DIV></DIV><img src ="http://www.blogjava.net/chengang/aggbug/34083.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chengang/" target="_blank">陈刚</a> 2006-03-07 15:01 <a href="http://www.blogjava.net/chengang/archive/2006/03/07/34083.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[JMX一步步来]　2、JMX简介</title><link>http://www.blogjava.net/chengang/archive/2006/03/07/34082.html</link><dc:creator>陈刚</dc:creator><author>陈刚</author><pubDate>Tue, 07 Mar 2006 07:00:00 GMT</pubDate><guid>http://www.blogjava.net/chengang/archive/2006/03/07/34082.html</guid><wfw:comment>http://www.blogjava.net/chengang/comments/34082.html</wfw:comment><comments>http://www.blogjava.net/chengang/archive/2006/03/07/34082.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/chengang/comments/commentRss/34082.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chengang/services/trackbacks/34082.html</trackback:ping><description><![CDATA[<DIV align=center>文/陈刚 from <A href="http://www.chengang.com.cn/">www.chengang.com.cn</A> at 2005-12-4</DIV>
<DIV></DIV>
<P>一、JMX简介</P>
<P>　　JMX是一种JAVA的正式规范，它主要目的是让程序且有被管理的功能，那么怎么理解所谓的“被管理”呢？试想你开发了一个软件（如ＷＥＢ网站），它是在２４小时不简断运行的，那么你可能会想要“监控”这个软件的运行情况，比如收到了多少数据，有多少人登录等等。或者你又想“配置”这个软件，比如现在访问人数比较多，你想把数据连接池设置得大一些。</P>
<P>　　当然，你也许会专门为这些管理来开发软件，但如果你借助JMX，则会发现创建这样的管理程序是如此简单。因为你无需为管理程序来开发界面，已经有通用的JMX管理软件，如MC4J，或者是用一般都附带提供的HTML网页来管理，你要做的仅仅是将自己要被管理和监控类的按照JMX规范修改一下即可。</P>
<P>　　中间件软件WebLogic的管理页面就是基于JMX开发的，而JBoss则整个系统都基于JMX构架。下面将JMX的一些概念，从JMX规范转帖如下：</P>
<P>二、JMX构架中的各层及相关的组件</P>
<OL>
<LI>工具层（Instrumentation Level）<BR>&nbsp;&nbsp;&nbsp;&nbsp;(a) MBeans（标准的，动态的，开放的和模型MBeans）<BR>&nbsp;&nbsp;&nbsp;&nbsp;(b) 通知模型：Notification、NotificationListener等类<BR>&nbsp;&nbsp;&nbsp;&nbsp;(c) MBean元数据类：Attribute、Opreator等类 
<LI>代理层（Agent Level）<BR>&nbsp;&nbsp;&nbsp;&nbsp;(a) MBean Server<BR>&nbsp;&nbsp;&nbsp;&nbsp;(b) 代理服务。如前一篇的HtmlAdaptorServer等。</LI></OL>
<P>以下是从网上找到的两个图：</P>
<P>（图1）<IMG style="DISPLAY: block" alt=1133692832597_4252.jpg src="http://blog.sohu.com/images/person/2005/12/4/1133692832597_4252.jpg" border=0></P>
<P>（图2）</P>
<P><IMG style="DISPLAY: block" alt=1133692869186_5136.gif src="http://blog.sohu.com/images/person/2005/12/4/1133692869186_5136.gif" border=0></P>
<P></P>
<P>　　MBean中有getter和setter的就是属性，如前一篇的Hello类中Name。如果只有getter则表示该属性只读。一共有四种MBean，如下：</P>
<OL>
<LI>标准MBeans（Standard MBeans）设计和实现是最简单的，这类MBean使用自己的方法名作为管理接口； 
<LI>动态MBeans（Dynamic MBeans）必须实现一个指定的接口，由于动态MBeans在运行期间暴露它们的管理接口，因此更为灵活； 
<LI>开放MBeans（Open MBeans）属于动态MBeans，这类MBean依靠基础数据类型来实现通用管理，并为友情用户进行自我声明； 
<LI>模型MBeans（Model MBeans）同样也是动态MBeans，这类MBeans是完全可配置的，在运行期间进行自我声明；它们为资源动态工具提供一个一般性的，有默认行为的MBeans类。</LI></OL>
<DIV>　　在前一篇中的Hello、HelloMBean就是一个标准MBeans（Standard MBeans）。后面接下来的几篇，我们会继续介绍其他几种MBean。</DIV><img src ="http://www.blogjava.net/chengang/aggbug/34082.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chengang/" target="_blank">陈刚</a> 2006-03-07 15:00 <a href="http://www.blogjava.net/chengang/archive/2006/03/07/34082.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jboss中JMX的连接与Mbean的获取</title><link>http://www.blogjava.net/chengang/archive/2006/03/07/34078.html</link><dc:creator>陈刚</dc:creator><author>陈刚</author><pubDate>Tue, 07 Mar 2006 06:54:00 GMT</pubDate><guid>http://www.blogjava.net/chengang/archive/2006/03/07/34078.html</guid><wfw:comment>http://www.blogjava.net/chengang/comments/34078.html</wfw:comment><comments>http://www.blogjava.net/chengang/archive/2006/03/07/34078.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/chengang/comments/commentRss/34078.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chengang/services/trackbacks/34078.html</trackback:ping><description><![CDATA[<DIV align=center>文/陈刚 from <A href="http://www.chengang.com.cn/"><FONT color=#222266>www.chengang.com.cn</FONT></A></DIV>
<P>给出一个例程吧<BR>（1）它需要Jboss的jbossall-client.jar包的支持<BR>（2）运行环境为Jboss3.2.6 + jdk5.0 + eclipse3.2M2。jdk5.0内置了JMX支持，如果你不是jdk5.0的话eclipse可能会报有会类找不到的错误<BR>（3）之前必须选启动Jboss<BR></P>
<DIV>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;java.util.Iterator;<BR></SPAN><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;java.util.Properties;<BR></SPAN><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;java.util.Set;<BR><BR></SPAN><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;javax.management.MBeanInfo;<BR></SPAN><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;javax.management.MBeanOperationInfo;<BR></SPAN><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;javax.management.MBeanParameterInfo;<BR></SPAN><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;javax.management.ObjectInstance;<BR></SPAN><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;javax.management.ObjectName;<BR></SPAN><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;javax.naming.InitialContext;<BR><BR></SPAN><SPAN style="COLOR: #0000ff">import</SPAN><SPAN style="COLOR: #000000">&nbsp;org.jboss.jmx.adaptor.rmi.RMIAdaptor;<BR><BR></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;TestJMX&nbsp;{<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">void</SPAN><SPAN style="COLOR: #000000">&nbsp;main(String[]&nbsp;args)&nbsp;</SPAN><SPAN style="COLOR: #0000ff">throws</SPAN><SPAN style="COLOR: #000000">&nbsp;Exception&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">Get&nbsp;RMIAdaptor&nbsp;Object</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Properties&nbsp;pro&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Properties();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pro.setProperty(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">java.naming.factory.initial</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">org.jnp.interfaces.NamingContextFactory</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pro.setProperty(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">java.naming.provider.url</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">jnp://localhost:1099</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pro.setProperty(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">java.naming.factory.url.pkgs</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">org.jboss.naming:org.jnp.interfaces</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InitialContext&nbsp;ic&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;InitialContext(pro);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RMIAdaptor&nbsp;server&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;(RMIAdaptor)&nbsp;ic.lookup(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">jmx/rmi/RMIAdaptor</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;Get&nbsp;the&nbsp;MBeanInfo&nbsp;for&nbsp;the&nbsp;JNDIView&nbsp;MBean</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ObjectName&nbsp;name&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;ObjectName(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">jboss:service=JNDIView</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MBeanInfo&nbsp;info&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;server.getMBeanInfo(name);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">JNDIView&nbsp;Class:&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;info.getClassName());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MBeanOperationInfo[]&nbsp;opInfo&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;info.getOperations();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">JNDIView&nbsp;Operations:&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;o&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;&nbsp;o&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;opInfo.length;&nbsp;o</SPAN><SPAN style="COLOR: #000000">++</SPAN><SPAN style="COLOR: #000000">)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MBeanOperationInfo&nbsp;op&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;opInfo[o];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;returnType&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;op.getReturnType();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;opName&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;op.getName();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.print(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;+&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;returnType&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;opName&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MBeanParameterInfo[]&nbsp;params&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;op.getSignature();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000">&nbsp;(</SPAN><SPAN style="COLOR: #0000ff">int</SPAN><SPAN style="COLOR: #000000">&nbsp;p&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">0</SPAN><SPAN style="COLOR: #000000">;&nbsp;p&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;params.length;&nbsp;p</SPAN><SPAN style="COLOR: #000000">++</SPAN><SPAN style="COLOR: #000000">)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MBeanParameterInfo&nbsp;paramInfo&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;params[p];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;pname&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;paramInfo.getName();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;type&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;paramInfo.getType();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(pname.equals(type))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.print(type);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">else</SPAN><SPAN style="COLOR: #000000"><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.print(type&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;name);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">if</SPAN><SPAN style="COLOR: #000000">&nbsp;(p&nbsp;</SPAN><SPAN style="COLOR: #000000">&lt;</SPAN><SPAN style="COLOR: #000000">&nbsp;params.length&nbsp;</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">1</SPAN><SPAN style="COLOR: #000000">)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.print(</SPAN><SPAN style="COLOR: #000000">&amp;apos;</SPAN><SPAN style="COLOR: #000000">,</SPAN><SPAN style="COLOR: #000000">&amp;apos;</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">)</SPAN><SPAN style="COLOR: #000000">"</SPAN><SPAN style="COLOR: #000000">);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">Get&nbsp;all&nbsp;MBeans</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set&nbsp;mbSet&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;server.queryMBeans(</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">,&nbsp;</SPAN><SPAN style="COLOR: #0000ff">null</SPAN><SPAN style="COLOR: #000000">);&nbsp;</SPAN><SPAN style="COLOR: #008000">//<BR></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">for</SPAN><SPAN style="COLOR: #000000">&nbsp;(Iterator&nbsp;it&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;mbSet.iterator();&nbsp;it.hasNext();)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ObjectInstance&nbsp;oi&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;(ObjectInstance)&nbsp;it.next();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(oi.getObjectName());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR></SPAN></DIV></DIV>
<P></P>
<P>这里有一段网上找到的代码,正好是实现了配置文件修改后重读的功能.<BR><BR>import java.io.File;<BR>import java.io.FileInputStream;<BR>import java.io.IOException;<BR>import java.net.URL;<BR>import java.util.Properties;<BR><BR>/** <BR>* @author Robbin Fan <BR>*/<BR>public class ConfigUtil {<BR><BR>private static Properties props = null;<BR>private static File configFile = null;<BR>private static long fileLastModified = 0L;<BR><BR>private static void init() {<BR>URL url = ConfigUtil.class.getClassLoader().getResource("global.properties");<BR>configFile = new File(url.getFile());<BR>fileLastModified = configFile.lastModified();<BR>props = new Properties();<BR>load();<BR>}<BR><BR>private static void load() {<BR>try {<BR>props.load(new FileInputStream(configFile));<BR>fileLastModified = configFile.lastModified();<BR>} catch (IOException e) {<BR>throw new RuntimeException(e);<BR>}<BR>}<BR><BR>public static String getConfig(String key) {<BR>if ((configFile == null) || (props == null))<BR>init();<BR>if (configFile.lastModified() &gt; fileLastModified)<BR>load();<BR>return props.getProperty(key);<BR>}<BR><BR>} </P>
<P></P>
<P>如果MBean就在本地，则可以用下面的方法来获得：</P>
<P>ThreadPoolMBean poolMBean = (ThreadPoolMBean) MBeanProxyExt.create(ThreadPoolMBean.class, objName);</P>
<P>还有一种远程获得的方法（从开源代码中看到的，未验证）</P>
<P>ThreadPoolMBean poolMBean = (ThreadPoolMBean) MBeanServerInvocationHandler.newProxyInstance(mbeanServer, objName, ThreadPoolMBean.class, false);</P><img src ="http://www.blogjava.net/chengang/aggbug/34078.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chengang/" target="_blank">陈刚</a> 2006-03-07 14:54 <a href="http://www.blogjava.net/chengang/archive/2006/03/07/34078.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[JMX一步步来]　1、JMX的Hello World</title><link>http://www.blogjava.net/chengang/archive/2006/03/07/34061.html</link><dc:creator>陈刚</dc:creator><author>陈刚</author><pubDate>Tue, 07 Mar 2006 06:29:00 GMT</pubDate><guid>http://www.blogjava.net/chengang/archive/2006/03/07/34061.html</guid><wfw:comment>http://www.blogjava.net/chengang/comments/34061.html</wfw:comment><comments>http://www.blogjava.net/chengang/archive/2006/03/07/34061.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/chengang/comments/commentRss/34061.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/chengang/services/trackbacks/34061.html</trackback:ping><description><![CDATA[<DIV>　　　　文/陈刚 from <A href="http://www.chengang.com.cn/">www.chengang.com.cn</A> at 2005-12-3<BR></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV><STRONG><BR>一、JMX简介</STRONG></DIV>
<DIV><STRONG></STRONG><BR>　　什么是JMX？在一篇网文中是这样说的："JMX(Java Management Extensions)是一个为应用程序植入管理功能的框架。JMX是一套标准的代理和服务，实际上，用户可以在任何Java应用程序中使用这些代理和服务实现管理"，这句话我现在看着还是不知所云，云里雾里。</DIV>
<DIV><BR>　　我们还是从JMX能给我们提供什么好处入手来理解吧。举一个应用实例：在一个系统中常常会有一些配置信息，比如服务的IP地址，端口号什么的，那么如何来写这些代码呢？</DIV>
<OL>
<LI>程序初哥一般是写死在程序里，到要改变时就去改程序，然后再编译发布；</LI>
<LI>程序熟手则一般把这些信息写在一个配置文件里（JAVA一般都是*.properties文件），到要改变时只要改配置文件，但还是重新启动系统，以便读取配置文件里的新值；</LI>
<LI>程序好手则会写一个段代码，把配置值缓存起来，系统在读值的时候，先看看配置文件有没有更动。如有更改则重读一遍，否则从缓存里读取值</LI>
<LI>程序高手则懂得取物为我所用，用JMX！把配置属性集中在一个类，然后写一个叫MBean的东东，再配置一下就轻松搞定了。而且JMX自动提供了一个WEB页面来给你来改变这些配置信息。</LI></OL>
<P><STRONG>二、准备工作</STRONG></P>
<P><STRONG></STRONG><BR>　　JMX是一份规范，SUN依据这个规范在JDK（1.3、1.4、5.0）提供了JMX接口。而根据这个接口的实现则有很多种，比如Weblogic的JMX实现、MX4J、JBoss的JMX实现。在SUN自己也实现了一份，不过在JDK1.4之前，这件JMX实现（一些JAR包）是可选的，你得去它的网站上下载。JDK5.0则内嵌了进来，安装JDK5.0就可以开发基于JMX的代码了。</P>
<DIV>
<DIV>
<DIV></DIV>
<DIV>　　但JDK5.0并非包含所有SUN的关于JMX的代码，有一些工具类是排除在JDK5.0之外的。下面根据所使用的JDK版本情况，谈一谈开发环境的准备。</DIV>
<DIV></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV>1、JDK1.3、1.4</DIV>
<DIV></DIV>
<DIV>　　去SUN网站下载SUN的JMX实现，共两个ZIP文件，下载网址：<A href="http://java.sun.com/products/JavaManagement/download.html">http://java.sun.com/products/JavaManagement/download.html</A>。</DIV>
<DIV></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV>（1）jmx-1_2_1-ri.zip</DIV>
<DIV>　　　解压后的lib目录包含：jmxri.jar、jmxtools.jar</DIV>
<DIV>（2）jmx_remote-1_0_1_03-ri.zip</DIV>
<DIV>　　　解压后的lib目录包含：jmxremote.jar、jmxremote_optional.jar、rmissl.jar</DIV>
<DIV></DIV>
<DIV></DIV>
<DIV>　　如果在DOS下用命令行开发，则把这五个JAR包加入到classpath系统变量中。如果你用Eclipse开发，则把JAR包加入到项目属性的Libratries（库）引用中。</DIV>
<DIV></DIV>
<DIV>2、JDK5.0</DIV>
<DIV></DIV>
<DIV>　　JDK5.0的jre\lib\rt.jar已经包含了jmxri.jar、jmxremote.jar、rmissl.jar三个包的代码。如果你用到jmxtools.jar、jmxremote_optional.jar的类，则需要将这两个类加入到classpath或Eclipse的项目库引用中。</DIV>
<DIV></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV>3、我使用的开发环境：JDK5.0 ＋ Eclipse3.2。</DIV>
<DIV></DIV>
<DIV>　　注：因为用到jmxtools.jar中的HtmlAdaptorServer类，所以将此包加入到项目库引用中。jmxremote_optional.jar暂时不用到，不管它。<BR></DIV>
<DIV></DIV>
<DIV><BR><STRONG>三、HelloWorld实例</STRONG></DIV>
<DIV><STRONG></STRONG></DIV>
<DIV><STRONG></STRONG></DIV>
<DIV></DIV>
<DIV>1、Hello是一个需要被管理的类（普通类）<BR></DIV>
<DIV>
<DIV style="BORDER-RIGHT: 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 1px; BORDER-LEFT: 1px solid; WIDTH: 100%; PADDING-TOP: 1px; BORDER-BOTTOM: 1px solid; HEIGHT: 18px"><PRE>/**<BR> * @author ChenGang 2005-12-3<BR> */<BR>public class Hello implements HelloMBean {<BR>    private String name;<BR>    public String getName() {<BR>        return name;<BR>    }<BR>    public void setName(String name) {<BR>        this.name = name;<BR>    }<BR>    public void printHello() {<BR>        System.out.println("Hello World, " + name);<BR>    }<BR>    public void printHello(String whoName) {<BR>        System.out.println("Hello , " + whoName);<BR>    }<BR>}</PRE></DIV></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV>2、要管理Hello则必须创建一个相应MBean，如下：</DIV>
<DIV></DIV>
<DIV>
<DIV style="BORDER-RIGHT: 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 1px; BORDER-LEFT: 1px solid; WIDTH: 100%; PADDING-TOP: 1px; BORDER-BOTTOM: 1px solid; HEIGHT: 18px"><PRE>/**<BR> * @author ChenGang 2005-12-3<BR> */<BR>public interface HelloMBean {<BR>    public String getName();<BR>    public void setName(String name);<BR>    public void printHello();<BR>    public void printHello(String whoName);<BR>} </PRE></DIV></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV>说明：包含在MBean中方法都将是可以被管理的。MBean起名是有规范的，就是原类名后加上MBean字样。</DIV>
<DIV>　</DIV>
<DIV>3、创建一个Agent类</DIV>
<DIV></DIV>
<DIV>
<DIV style="BORDER-RIGHT: 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: 1px solid; PADDING-LEFT: 4px; PADDING-BOTTOM: 1px; BORDER-LEFT: 1px solid; WIDTH: 100%; PADDING-TOP: 1px; BORDER-BOTTOM: 1px solid; HEIGHT: 18px"><PRE>import javax.management.MBeanServer;<BR>import javax.management.MBeanServerFactory;<BR>import javax.management.ObjectName;<BR>import com.sun.jdmk.comm.HtmlAdaptorServer;</PRE><PRE>public class HelloAgent {</PRE><PRE>    public static void main(String[] args) throws Exception {<BR>        MBeanServer server = MBeanServerFactory.createMBeanServer();</PRE><PRE>        ObjectName helloName = new ObjectName("chengang:name=HelloWorld");<BR>        server.registerMBean(new Hello(), helloName);</PRE><PRE>        ObjectName adapterName = new ObjectName("HelloAgent:name=htmladapter,port=8082");<BR>        HtmlAdaptorServer adapter = new HtmlAdaptorServer();<BR>        server.registerMBean(adapter, adapterName);</PRE><PRE>        adapter.start();<BR>        System.out.println("start.....");<BR><BR><BR><BR><BR>    }<BR>} </PRE></DIV></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV>说明：</DIV>
<UL>
<LI>先创建了一个MBeanServer，用来做MBean的容器 </LI>
<LI>将Hello这个类注入到MBeanServer中，注入需要创建一个ObjectName类 </LI>
<LI>创建一个AdaptorServer，这个类将决定MBean的管理界面，这里用最普通的Html型界面。AdaptorServer其实也是一个MBean。</LI>
<LI>chengang:name=HelloWorld的名字是有一定规则的，格式为：“域名:name=MBean名称”，域名和MBean名称都可以任意取。</LI></UL>
<DIV>4、运行HelloAgent，然后打开网页：<A href="http://localhost:8082/">http://localhost:8082/</A>，效果图如下：</DIV>
<DIV></DIV>
<DIV></DIV>
<DIV><IMG style="DISPLAY: block" alt=1133616885971_1841.jpg src="http://blog.sohu.com/images/person/2005/12/3/1133616885971_1841.jpg" border=0></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV>单击“name=HelloWorld”链接进入，出现如下页面</DIV>
<DIV></DIV>
<DIV></DIV>
<DIV></DIV>
<DIV><IMG style="DISPLAY: block" alt=1133616990271_7574.jpg src="http://blog.sohu.com/images/person/2005/12/3/1133616990271_7574.jpg" border=0></DIV></DIV></DIV>
<P>依照下面红线的步骤操作之后，在控制台（我用Eclipse就是console视图）得到如下输出：</P>
<P><IMG style="DISPLAY: block" alt=1133617125401_8322.jpg src="http://blog.sohu.com/images/person/2005/12/3/1133617125401_8322.jpg" border=0></P>
<P><STRONG>五、总结</STRONG></P>
<P>　　在实际系统中我们可以把name变成决定数库链接池的变量，这样我就可以对系统的运行参数进行实现的监控和配置（管理）。而且也可以对一些方法（如printHello）进行远程调用了。</P>
<P>　　预告：下一篇将对JMX进行一些介绍，借助本篇的HelloWorld实例来灌输一些概念。</P>
<P><STRONG>作者简介</STRONG></P>
<P>陈刚，广西桂林人，著作有《Eclipse从入门到精通》<BR>您可以通过其博客了解更多信息和文章：<A href="http://www.chengang.com.cn/"><FONT color=#000033>http://www.chenGang.com.cn</FONT></A> </P><img src ="http://www.blogjava.net/chengang/aggbug/34061.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/chengang/" target="_blank">陈刚</a> 2006-03-07 14:29 <a href="http://www.blogjava.net/chengang/archive/2006/03/07/34061.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>