日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

从零开始玩转JMX(四)——Apache Commons Modeler Dynamic MBean

發布時間:2024/4/11 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 从零开始玩转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的代碼如下:

package com.test.jmx.DynamicMBean;import javax.management.*; import java.lang.reflect.Constructor; import java.util.Iterator;/*** Created by hidden on 2016/10/9.*/ public class HelloDynamic implements DynamicMBean {private String name;private MBeanInfo mBeanInfo = null;private String className;private String description;private MBeanAttributeInfo[] attributes;private MBeanConstructorInfo[] constructors;private MBeanOperationInfo[] operations;MBeanNotificationInfo[] mBeanNotificationInfoArray;private void init(){className = this.getClass().getName();description = "Simple implementation of a dynamic MBean.";attributes = new MBeanAttributeInfo[1];constructors = new MBeanConstructorInfo[1];operations = new MBeanOperationInfo[1];mBeanNotificationInfoArray = new MBeanNotificationInfo[0];}private void buildDynamicMBean(){Constructor[] thisConstructors = this.getClass().getConstructors();constructors[0] = new MBeanConstructorInfo("HelloDynamic(): Constructs a HelloDynamic Object",thisConstructors[0]);attributes[0] = new MBeanAttributeInfo("name","java.lang.String","Name:name string.",true,true,false);MBeanParameterInfo[] params = null;operations[0] = new MBeanOperationInfo("print","print():print the name",params,"void",MBeanOperationInfo.INFO);mBeanInfo = new MBeanInfo(className,description,attributes,constructors,operations,mBeanNotificationInfoArray);}public HelloDynamic(){init();buildDynamicMBean();}private void dynamicAddOperation(){init();operations = new MBeanOperationInfo[2];buildDynamicMBean();operations[1] = new MBeanOperationInfo("print1","print1():print the name",null,"void",MBeanOperationInfo.INFO);mBeanInfo = new MBeanInfo(className,description,attributes,constructors,operations,mBeanNotificationInfoArray);}@Overridepublic Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException {if (attribute == null) {return null;}if (attribute.equals("Name")) {return name;}return null;}@Overridepublic void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException {if (attribute == null) {return;}String Name = attribute.getName();Object value = attribute.getValue();try {if (Name.equals("Name")) {if (value == null) {name=null;} else if (Class.forName("java.lang.String").isAssignableFrom(value.getClass())) {name = (String) name;}}} catch (ClassNotFoundException e) {e.printStackTrace();}}@Overridepublic AttributeList getAttributes(String[] attributes) {if (attributes == null) {return null;}AttributeList resultList = new AttributeList(); // if (attributes.length == 0) { // return resultList; // }for(int i=0;i<attributes.length;i++){try {Object value = getAttribute(attributes[i]);resultList.add(new Attribute(attributes[i],value));} catch (AttributeNotFoundException e) {e.printStackTrace();} catch (MBeanException e) {e.printStackTrace();} catch (ReflectionException e) {e.printStackTrace();}}return resultList;}@Overridepublic AttributeList setAttributes(AttributeList attributes) {if (attributes == null) {return null;}AttributeList resultList = new AttributeList();if(attributes.isEmpty()){return resultList;}for(Iterator i = attributes.iterator();i.hasNext();){Attribute attr = (Attribute) i.next();try {setAttribute(attr);String name = attr.getName();Object value = getAttribute(name);resultList.add(new Attribute(name,value));} catch (AttributeNotFoundException e) {e.printStackTrace();} catch (InvalidAttributeValueException e) {e.printStackTrace();} catch (MBeanException e) {e.printStackTrace();} catch (ReflectionException e) {e.printStackTrace();}}return resultList;}@Overridepublic Object invoke(String actionName, Object[] params, String[] signature) throws MBeanException, ReflectionException {if(actionName.equals("print")){System.out.println("Hello, "+name+",this is HelloDynamic!");dynamicAddOperation();return null;}else if(actionName.equals("print1")){System.out.println("這是動態增加的一個方法print1");return null;}else {throw new ReflectionException(new NoSuchMethodException(actionName),"Cannot find the operation "+actionName+" in "+className);}}@Overridepublic MBeanInfo getMBeanInfo() {return mBeanInfo;} }

通過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! 這是動態增加的一個方法print1

wanna more?

  • 從零開始玩轉JMX(一)——簡介和Standard MBean
  • 從零開始玩轉JMX(二)——Condition
  • 從零開始玩轉JMX(三)——Model MBean
  • 從零開始玩轉JMX(四)——Apache Commons Modeler & Dynamic MBean

  • 參考資料

  • JMX整理
  • JMX簡介
  • http://blog.csdn.net/DryKillLogic/article/category/762777
  • 用Apache的commons-modeler來輔助開發JMX
  • 歡迎跳轉到本文的原文鏈接:https://honeypps.com/java/jmx-quick-start-4-dynamic-mbean/


    歡迎支持筆者新作:《深入理解Kafka:核心設計與實踐原理》和《RabbitMQ實戰指南》,同時歡迎關注筆者的微信公眾號:朱小廝的博客。


    總結

    以上是生活随笔為你收集整理的从零开始玩转JMX(四)——Apache Commons Modeler Dynamic MBean的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。