从零开始玩转JMX(四)——Apache Commons Modeler Dynamic MBean
歡迎支持筆者新作:《深入理解Kafka:核心設計與實踐原理》和《RabbitMQ實戰指南》,同時歡迎關注筆者的微信公眾號:朱小廝的博客。
歡迎跳轉到本文的原文鏈接:https://honeypps.com/java/jmx-quick-start-4-dynamic-mbean/
Apache Commons Modeler
前面的Model MBean的創建方式看上去特別復雜,一個簡單功能的類ModelMBeanUtils 寫了很多代碼,那有木有簡單點的方式呢,答案是肯定的,這里就引出了Apache Commons Modeler(使用這個需要在classpath中導入commons-modeler-2.0.1.jar以及modeler的依賴項目commons-logging-1.1.3.jar,下載地址:http://commons.apache.org/proper/commons-modeler/download_modeler.cgi),使用Apache的Moleler庫創建Model MBean最大幫助是,我們不需要再寫復雜的代碼來創建ModelMBeanInfo對象了。只需要一個MBean描述符(實際上就是一個xml配置文件,Apache Commons Modeler將ModelMBeanUtils 復雜的創建過程轉移到xml中來配置,然后自身模塊創建對象代替ModelMBeanUtils 的功能,簡化用戶的操作)來對Model MBean進行描述,就可以輕松的創建Model MBean.
下面來講前面的Hello.java和HelloAgent.java的例子采用Apache Commons Modele進行改造。
首先還是Hello.java,和Model MBean中的一樣,沒有implements任何接口。
package com.test.jmx.modeler;public class Hello{private String name;public String getName() {return name;}public void setName(String name) {this.name= name;}public void printHello() {System.out.println("Hello World, "+name);}public void printHello(String whoName) {System.out.println("Hello, "+whoName);} }接下去就是最關鍵的描述文件(mbeans-descriptors.xml)了:
<?xml version="1.0" encoding="UTF-8" ?> <mbeans-descriptors><mbean name="Hello" description="the hello bean" domain="MyMBean" group="helloGroup" type="com.test.jmx.modeler.Hello"><attribute name="name" description="a name attribute" type="java.lang.String" writeable="true"/><operation name="printHello" description="public void printHello()" impact="ACTION" returnType="void"/><operation name="printHello" description="public void printHello(String whoName)" impact="ACTION" returnType="void"><parameter name="whoName" description="method parameter of printHello" type="java.lang.String"></parameter> </operation></mbean> </mbeans-descriptors>描述文件的名字可以隨意,最主要的是要和下面的HelloAgent.java對應起來。
通過這個xml文件的定義就描述了Model MBean所需要的metadata信息和一個基本的ModelMBean實現。
關于這個xml文件有幾個需要說明的地方:
<mbean>的屬性classname,name,type:
- name屬性是每個MBean被Registry對象注冊的對象名
- type屬性是真正被管理資源的全面(包括包名)
- classname屬性是用戶擴展的用于實現代理功能的Model MBean的全名,如果不提供Modeler會使用BaseModelMBean;如果提供了代理的ModelMBean對象,在使用時可以使用如下的代碼樣本訪問他所代理的資源對象。
其余的標簽就比較好理解了。綜述:上面所示代碼聲明了一個Model MBean, 唯一標示是“Hello”,該MBean負責管理的對象是com.test.jmx.modeler.Hello的實例。域是MyMBean。這個MBean暴露了一個屬性name和兩個方法printHello()和printHello(String whoName).
下面是新的HelloAgent.java的代碼:
package com.test.jmx.modeler;import com.sun.jdmk.comm.HtmlAdaptorServer; import org.apache.commons.modeler.ManagedBean; import org.apache.commons.modeler.Registry;import javax.management.MBeanServer; import javax.management.ObjectName; import javax.management.modelmbean.ModelMBean; import java.io.InputStream;public class HelloAgent {public static void main(String[] args) throws Exception { // 需要將xml信息讀入到Registry對象中Registry registry = Registry.getRegistry(null,null);InputStream stream = HelloAgent.class.getResourceAsStream("mbeans-descriptors.xml");registry.loadMetadata(stream);MBeanServer server = registry.getMBeanServer();// 之前是:MBeanServer server = ManagementFactory.getPlatformMBeanServer();ManagedBean managed = registry.findManagedBean("Hello");ObjectName helloName = new ObjectName(managed.getDomain()+":name=HelloWorld"); // 以前是Hello hello = new Hello(); 為什么要多個createMBean?因為現在的寫法沒有寫MBean,所以才要動態生成一個,以前就直接 // 把new hello()注冊到MBeanServer就可以了,server會自動找到它的HelloMBean接口文件。ModelMBean hello = managed.createMBean(new Hello());server.registerMBean(hello,helloName);ObjectName adapterName = new ObjectName(managed.getDomain()+":name = htmladapter,port=8082");HtmlAdaptorServer adapter = new HtmlAdaptorServer();server.registerMBean(adapter,adapterName);adapter.start();} }注意這里的Registry是指org.apache.commons.modeler.Registry,因為JMX自身也有一個Registry(java.rmi.registry.Registry)。通過Modeler組件提供的Registry對象,可以很方便的完成MBeanServer的創建。
運行效果和之前的一樣,這里就不贅述了,有興趣的小伙伴可以試一下。
Dynamic MBean
四種類型的MBean,前面所講的都是常用的,現在還剩兩種Open MBean就不講述了,這里簡單記錄下Dynamic MBean。
Dynamic MBean不需要自定義MBean接口,只需要實現DynamicMBean接口即可,Dynamic MBean沒有任何明顯些在代碼里的屬性和方法,所有的屬性和方法都是通過反射結合JMX提供的輔助元數據從而動態生成。
下面的代碼中首先定義了一個屬性name和一個方法print,之后在管理界面(localhost:8082)中點擊print之后生成一個print1的方法。
Dynamic MBean的代碼如下:
通過Agent調用Dynamic MBean:
package com.test.jmx.DynamicMBean;import com.sun.jdmk.comm.HtmlAdaptorServer;import javax.management.*; import java.lang.management.ManagementFactory; import java.util.concurrent.TimeUnit;public class HelloAgent {public static void main(String[] args) throws MalformedObjectNameException, NotCompliantMBeanException, InstanceAlreadyExistsException, MBeanRegistrationException {MBeanServer server = ManagementFactory.getPlatformMBeanServer();ObjectName helloName = new ObjectName("MyMBean:name=helloDynamic");HelloDynamic hello = new HelloDynamic();server.registerMBean(hello,helloName);ObjectName adapterName = new ObjectName("MyMBean:name=htmladapter");HtmlAdaptorServer adapter = new HtmlAdaptorServer();server.registerMBean(adapter,adapterName);adapter.start();} }運行效果圖如下:
運行結果:
Hello, null,this is HelloDynamic! 這是動態增加的一個方法print1wanna more?
參考資料
歡迎跳轉到本文的原文鏈接:https://honeypps.com/java/jmx-quick-start-4-dynamic-mbean/
歡迎支持筆者新作:《深入理解Kafka:核心設計與實踐原理》和《RabbitMQ實戰指南》,同時歡迎關注筆者的微信公眾號:朱小廝的博客。
總結
以上是生活随笔為你收集整理的从零开始玩转JMX(四)——Apache Commons Modeler Dynamic MBean的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从零开始玩转JMX(三)——Model
- 下一篇: sbt安装与配置