国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > 綜合 > 正文

擴展 Spring 的 JMX 支持(2)

2024-07-21 02:14:34
字體:
供稿:網(wǎng)友
  擴展 spring jmx 導出器

  為了使用擴展的 modelmbean,需要覆蓋 spring mbeanexporter 中的 createmodelmbean() 方法。因為可以注入裝配器屬性,所以必須知道它可能不是我所期待的這一事實。可以在構(gòu)造函數(shù)中設置所需要的裝配器,但是當裝配器改變時需要返回一個普通 modelmbean。所要做的就是緩存一個 mbeaninfoassembler 的本地引用,并在創(chuàng)建新的 modelmbean 時檢查它是什么類型的。清單 2 顯示了所有這些改變:

清單 2. mbeandescriptorenabledexporter

      package com.claudeduguay.mbeans.spring; import javax.management.*; import javax.management.modelmbean.*; import org.springframework.jmx.export.*; import org.springframework.jmx.export.assembler.*; public class mbeandescriptorenabledexporter extends mbeanexporter {   protected mbeaninfoassembler mbeaninfoassembler;      public mbeandescriptorenabledexporter()   {     setassembler(new mbeandescriptorbasedassembler());   }      public modelmbean createmodelmbean() throws mbeanexception   {     if (mbeaninfoassembler instanceof mbeandescriptorbasedassembler)     {       return new modelmbeanextension();     }     return super.createmodelmbean();   }      public void setassembler(mbeaninfoassembler mbeaninfoassembler)   {     this.mbeaninfoassembler = mbeaninfoassembler;     super.setassembler(mbeaninfoassembler);   } } 

  在使用這個擴展的類時,可以用標準 spring 語言改變裝配器,并在需要時回到默認的行為。在大多數(shù)情況下,如果最終繞過擴展,那么就不值得使用這個版本。不過,如果想要以新的定制裝配器使用擴展的 modelmbean,那么現(xiàn)在可以這樣做。

  構(gòu)建一個定制的裝配器

  這個定制裝配器的主要任務是查找與管理的類有關(guān)的元數(shù)據(jù)映射文件。找到這個文件后,就裝載它并生成必要的 modelmbeaninfo 實例。為此,我只是實現(xiàn)了 spring mbeaninfoassembler 實例建立這個文件的相關(guān)類路徑,用靜態(tài) mbeandescriptorutil.read() 方法裝載它并返回結(jié)果,如清單 3 所示:

清單 3. mbeandescriptorbasedassembler

  package com.claudeduguay.mbeans.spring; import java.io.*; import javax.management.modelmbean.*; import org.springframework.core.io.*; import org.springframework.jmx.export.assembler.*; import com.claudeduguay.mbeans.model.*; public class mbeandescriptorbasedassembler   implements mbeaninfoassembler {   public modelmbeaninfo getmbeaninfo(     object managedbean, string beankey)   {     string name = managedbean.getclass().getname();     string path = name.replace('.', '/') + ".mbean.xml";          classpathresource resource = new classpathresource(path);     inputstream input = null;     try     {       input = resource.getinputstream();       mbeandescriptor descriptor = mbeandescriptorutil.read(input);       return descriptor.creatembeaninfo();     }     catch (exception e)     {       throw new illegalstateexception(         "unable to load resource: " + path);     }     finally     {       if (input != null)       {         try { input.close(); } catch (exception x) {}       }     }   } } 


  這個 mbeandescriptorbasedassembler 忽略 bean 鍵參數(shù)并直接用受管 bean 引用創(chuàng)建所需的 modelmbeaninfo 實例。

  示例

  在本文其余部分,我將著重展示這個 spring jmx 擴展的使用。為此,使用一個假想的服務,它開放兩個方法和一個屬性,因此表現(xiàn)了典型的用例。

  exampleservice 是一個 java 對象,它在被調(diào)用時只是向控制臺進行輸出,如清單 4 所示:

清單 4. exampleservice

      package com.claudeduguay.jmx.demo.server; public class exampleservice {   protected string propertyvalue = "default value";      public exampleservice() {}      public string getpropertyvalue()   {     system.out.println("exampleservice: get property value");     return propertyvalue;   }   public void setpropertyvalue(string propertyvalue)   {     system.out.println("exampleservice: set property value");     this.propertyvalue = propertyvalue;   }   public void startservice()   {     system.out.println("exampleservice: start service called");   }   public void stopservice()   {     system.out.println("exampleservice: stop service called");   } } 

  對管理員友好的消息

  這個擴展的描述符可以幾乎直接關(guān)聯(lián)屬性和操作。描述符方法優(yōu)于內(nèi)省式方法的主要一點是可以提供更特定的消息。通知描述符的配置選項有賴于類型(xml)屬性的命名規(guī)范。實際的名字是任意的,但是代碼會被類型中的 set.name、before.name 和 after.name 樣式觸發(fā)。在這種情況下,我將 set 通知與 propertyvalue (jmx)屬性關(guān)聯(lián),將 before 與 after 通知與 startservice() 與 stopservice() 方法關(guān)聯(lián)。同樣,這些擴展使我可以很好利用描述性的消息。

  在清單 5 中,可以看到定義了一個屬性和兩個方法。通知描述符定義了方法的之前和之后事件以及一個屬性設置通知:

清單 5. exampleservice.mbean.xml
      <?xml version="1.0"?> <mbean name="exampleservice" description="example service"   type="com.claudeduguay.jmx.demo.server.exampleservice">   <attribute name="propertyvalue"     description="property value access" type="java.lang.string"     readable="true" writable="true" />   <operation name="stopservice"     description="stop example service" />   <operation name="startservice"     description="start example service" />   <notification name="propertyvalueset"     types="example.service.set.propertyvalue"     description="propertyvalue was set" />   <notification name="beforestartservice"     types="example.service.before.startservice"     description="example service is starting" />   <notification name="afterstartservice"     types="example.service.after.startservice"     description="example service is started" />   <notification name="beforestopservice"     types="example.service.before.stopservice"     description="example service is stopping" />   <notification name="afterstopservice"     types="example.service.after.stopservice"     description="example service is stopped" />    </mbean> 

  配置服務器

  要在客戶機/服務器環(huán)境中運行這個例子,需要配置和啟動一個 mbeanserver 實例。為此,我使用 java 5.0 mbeanserver 實例,它保證我可以使用 jvm 中提供的管理擴展,同時管理自己的代碼。如果愿意,還可以運行 mbeanserver 的多個實例,您愿意的話也可以自己試一試作為練習。

  就像 java 5.0 一樣,spring 框架使您可以配置自己的 mbeanserver 實例。我選擇使用 java 5.0,因為它支持 jsr-160 連接器,我的客戶機代碼會需要它。

清單 6. springjmxserver

      package com.claudeduguay.jmx.demo.server; import org.springframework.context.*; import org.springframework.context.support.*; import mx4j.tools.adaptor.http.*; /*  * to use the springjmxserver, use the following command line  * arguments to activate the java 1.5 jmx server.  *   * -dcom.sun.management.jmxremote.port=8999  * -dcom.sun.management.jmxremote.ssl=false  * -dcom.sun.management.jmxremote.authenticate=false  */ public class springjmxserver {   public static void main(string[] args)     throws exception   {     string spring_file =       "com/claudeduguay/jmx/demo/server/springjmxserver.xml";     applicationcontext context =       new classpathxmlapplicationcontext(spring_file);     httpadaptor httpadaptor =       (httpadaptor)context.getbean("httpadaptor");     httpadaptor.start();   } } 

  由于有了 mbeandescriptorenabledexporter,服務器的 spring 配置文件非常簡單。除了聲明 exampleservice,我增加了開放一個 http 適配器和連接 xsltprocessor 到 httpadaptor 所需要的 mx4j 項。注意這是 spring 的 ioc 實現(xiàn)非常有用的一個領(lǐng)域。清單 7 顯示了我的 springjmxserver 實例的 spring 配置文件:

清單 7. springjmxserver.xml

      <?xml version="1.0" encoding="utf-8"?> <!doctype beans public "-//spring//dtd bean//en"   "http://www.springframework.org/dtd/spring-beans.dtd"> <beans>   <bean id="exporter" class=     "com.claudeduguay.mbeans.spring.mbeandescriptorenabledexporter">     <property name="beans">       <map>         <entry key="services:name=exampleservice"           value-ref="exampleservice" />         <entry key="mx4j:name=httpadaptor"           value-ref="httpadaptor" />         <entry key="mx4j:name=xsltprocessor"           value-ref="xsltprocessor" />       </map>     </property>   </bean>      <bean id="xsltprocessor"     class="mx4j.tools.adaptor.http.xsltprocessor" />   <bean id="httpadaptor"     class="mx4j.tools.adaptor.http.httpadaptor">     <property name="processor" ref="xsltprocessor"/>     <property name="port" value="8080"/>   </bean>      <bean id="exampleservice"     class="com.claudeduguay.jmx.demo.server.exampleservice" /> </beans> 

  如果愿意(假定您遵循了我的設置),那么現(xiàn)在就可以運行這個服務器了。它會注冊 exampleservice 并運行 http 適配器。不要忘記使用注釋中提到的命令行參數(shù)啟動 java 5.0 mbeanserver,否則會得到默認實例,客戶機示例就不能工作了。

  運行客戶機代碼
    
  啟動服務器后,可以運行如清單 8 所示的客戶機代碼看看會發(fā)生什么。這段代碼實現(xiàn)了 jmx notificationlistener 接口,這樣就可以交互式地看到所發(fā)生的事情。連接后,可以注冊監(jiān)聽器,然后觸發(fā)幾個調(diào)用、啟動和停止服務、設置和取得屬性。在每一種情況下,都應當在控制臺上看到一個確認操作的通知消息。

清單 8. springjmxclient

      package com.claudeduguay.jmx.demo.client; import java.util.*; import javax.management.*; import javax.management.remote.*; public class springjmxclient implements notificationlistener {   public void handlenotification(     notification notification, object handback)    {     system.out.println(       "notification: " + notification.getmessage());   }      public static void main(string[] args)     throws exception   {     springjmxclient listener = new springjmxclient();          string address =       "service:jmx:rmi:///jndi/rmi://localhost:8999/jmxrmi";     jmxserviceurl serviceurl = new jmxserviceurl(address);     map<string,object> environment = null;     jmxconnector connector =       jmxconnectorfactory.connect(serviceurl, environment);     mbeanserverconnection mbeanconnection =       connector.getmbeanserverconnection();          objectname exampleservicename =       objectname.getinstance("services:name=exampleservice");     mbeanconnection.addnotificationlistener(       exampleservicename, listener, null, null);          mbeanconnection.invoke(       exampleservicename, "startservice", null, null);     mbeanconnection.setattribute(exampleservicename,       new attribute("propertyvalue", "new value"));     system.out.println(mbeanconnection.getattribute(       exampleservicename, "propertyvalue"));     mbeanconnection.invoke(       exampleservicename, "stopservice", null, null);   } }  

  由于 http 適配器也是可用的,可以試著使用 mx4j (通過一個到端口 8080 的瀏覽器連接)管理同樣的方法和屬性。如果同時讓客戶機代碼運行,那么也會看到這些操作的通知。

  結(jié)束語

  在本文中,我展示了如何擴展 spring 的 jmx 支持以滿足應用程序的特定需求。在這里,我使用了 spring 的基于容器的體系結(jié)構(gòu)和 aop 框架來為 jmx 方法和屬性增加通知事件。當然,我只觸及到了 spring jmx 能力的皮毛。還可以有許多其他擴展,spring 和 jmx 都是很大的主題,每一個都值得進一步研究。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 延安市| 辽阳市| 安康市| 海淀区| 莱州市| 临海市| 项城市| 西城区| 孟连| 贡山| 哈巴河县| 宝应县| 罗源县| 开化县| 六盘水市| 延吉市| 缙云县| 建宁县| 深泽县| 丰原市| 隆回县| 西畴县| 任丘市| 新民市| 明溪县| 修水县| 蚌埠市| 临泉县| 杂多县| 安康市| 星子县| 砀山县| 息烽县| 德兴市| 莲花县| 邵阳县| 繁昌县| 定州市| 新营市| 普兰县| 米泉市|