jmxbean

之前讲了在使用标准的MBean时,客户端代码中需要包含接口,通过JMX生成这个接口的proxy实例,来调用。

 

但是,对于MXBeans我们不需要知道被调用的类型。还是直接通过例子来看。

 

首先还是要定义一个接口,接口的名字要以MXbean结尾。

 

 

Java代码   收藏代码
  1. package com.example;   
  2.    
  3. public interface QueueSamplerMXBean {   
  4.     public Sample getSample();   
  5.     public void clearQueue();   
  6. }  
 

 

然后就是他的实现:

 

Java代码   收藏代码
  1. package com.example.mxbeans;   
  2.    
  3. import java.util.Date;   
  4. import java.util.Queue;   
  5.    
  6. public class QueueSampler implements QueueSamplerMXBean {   
  7.        
  8.     private Queue<String> queue;   
  9.        
  10.     public QueueSampler(Queue<String> queue) {   
  11.        this.queue = queue;   
  12.     }   
  13.        
  14.     public Sample getSample() {   
  15.         synchronized (queue) {   
  16.             return new Sample(new Date(), queue.size(), queue.peek());   
  17.         }   
  18.     }   
  19.        
  20.     public void clearQueue() {   
  21.         synchronized (queue) {   
  22.             queue.clear();   
  23.         }   
  24.     }   
  25. }   

 

 跟标准MBean不同,MXbean的实现类的类名不需要跟接口对应,比如上面的实现,类名可以改成叫MyQueueSampler等。

这个实现类实现了接口里面定义的两个方法。

 

下面就是存放在上面的Queue里面的对象类,这其实就是一个java bean:

 

Java代码   收藏代码
  1. public class Sample {   
  2.        
  3.     private final Date date;   
  4.     private final int size;   
  5.     private final String head;   
  6.        
  7.     @ConstructorProperties({"date""size""head"})   
  8.     public Sample(Date date, int size, String head) {   
  9.         this.date = date;   
  10.         this.size = size;   
  11.         this.head = head;   
  12.     }   
  13.        
  14.     public Date getDate() {   
  15.         return date;   
  16.     }   
  17.        
  18.     public int getSize() {   
  19.         return size;   
  20.     }   
  21.        
  22.     public String getHead() {   
  23.         return head;   
  24.     }   
  25. }  
 

 

在这个bean里面,构造函数上有一个annotation,@ConstructorProperties,我们一会再解释。

 

然后就是注册这个MXBean的类,这个类其实就跟标准MBean的注册一样的,

 

 

Java代码   收藏代码
  1. package com.example.mxbeans;   
  2.    
  3. import java.lang.management.ManagementFactory;   
  4. import java.util.Queue;   
  5. import java.util.concurrent.ArrayBlockingQueue;   
  6. import javax.management.MBeanServer;   
  7. import javax.management.ObjectName;   
  8.    
  9. public class Main {   
  10.    
  11.     public static void main(String[] args) throws Exception {   
  12.         MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();   
  13.            
  14.         ObjectName name =   
  15.                 new ObjectName("com.example.mxbeans:type=QueueSampler");   
  16.            
  17.         Queue<String> queue = new ArrayBlockingQueue<String>(10);   
  18.         queue.add("Request-1");   
  19.         queue.add("Request-2");   
  20.         queue.add("Request-3");   
  21.         QueueSampler mxbean = new QueueSampler(queue);   
  22.            
  23.         mbs.registerMBean(mxbean, name);   
  24.            
  25.         System.out.println("Waiting...");   
  26.         Thread.sleep(Long.MAX_VALUE);   
  27.     }   
  28. }  
 

 

在这里,在队列中加了3个数据,用这个队列创建了一个MBean对象,并把它注册到MBean server里。

然后我们运行这个程序:

java com.example.mxbeans.Main

 

然后打开jconsole,连接到刚才的Main进程。打开刚才注册的MBean对象,查看他的属性Sample:


我们可以看到Sample的值是CompositeDataSupport,而不是我们定义的Sample类的类名。这是因为,在MXbean里,MBean里面使用的数据类型,都会被转换成CompositeData类型,他是一个接口,CompositeDataSupport是他的实现,对于大多数普通对象,都可以被直接转换成CompositeDataSupport类型。就好像一个Map类型,只要里面的数据都是String,int这样的类型,就能转换成一个字符串,同样的道理,在MXBean里,所有的对象,都是被转换成CompositeDataSupport,来发送到客户端的。

 

我们在Sample类的构造函数里面,使用了@ConstructorProperties({"date", "size", "head"}),其实就是告诉JMX在创建Sample对象的时候,需要几个参数,分别叫什么。

 

然后在JConsole中,我们双击CompositeDataSupport,就可以看到Sample对象里面的3个成员。


 

因为在QueueSamplerMXBean里面,只定义了getSample方法,所以只能看,你们可以试着加一个add方法,在调用 的时候,就能看到JMX会为我们提供创建Sample对象时需要的3个成员的输入框。

 

如果是标准MBean,在Sample的值那一列,就无法显示正确的类型,更无法查看对象,,因为jconsole根本找不到sample类。除非你在启动JConsole的时候,把Sample类所在的目录作为classpath。

 

通过使用JConsole,我们就能看出MXBean和普通bean的区别。

 

最后,再看看在客户端使用时的区别:

 

 

Java代码   收藏代码
  1. import java.util.Date;  
  2.   
  3. import javax.management.MBeanServerConnection;  
  4. import javax.management.ObjectName;  
  5. import javax.management.openmbean.CompositeData;  
  6. import javax.management.remote.JMXConnector;  
  7. import javax.management.remote.JMXConnectorFactory;  
  8. import javax.management.remote.JMXServiceURL;  
  9.   
  10. public class SamplerMXBClient {  
  11.   
  12.     public static void main(String[] args) {  
  13.   
  14.         try {  
  15.             JMXServiceURL url = new JMXServiceURL(  
  16.                     "service:jmx:rmi:///jndi/rmi://localhost:8888/jmxrmi");  
  17.             JMXConnector jmxc = JMXConnectorFactory.connect(url, null);  
  18.             MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();  
  19.   
  20.             ObjectName name = new ObjectName("com.example.mxbeans:type=QueueSampler");  
  21.             CompositeData sampleComp = (CompositeData)mbsc.getAttribute(name, "Sample");  
  22.             Date sampleDate = (Date) sampleComp.get("date");  
  23.             System.out.println("sampleDate = " + sampleDate);             
  24.         } catch (Exception e) {  
  25.             e.printStackTrace();  
  26.         }  
  27.     }  
  28. }  
 

在这个代码里,我们没有使用QueueSampler来得到MBean对象的引用,而且,对这个对象里面Sample属性,也是使用CompositeData来获得,然后,再得到里面的date属性。

 

从这个代码就可以看出来,对于MXBean类型的MBean使用,我们完全不需要知道对方的类,参数类型,就可以通过CompositeData来得到其数据。

 

但是,对于稍微复杂的数据,如果都要这样去取,那是一件很麻烦的事情,所以,我们还是可以用类似标准MBean的方式,来得到:

 

Java代码   收藏代码
  1. QueueSamplerMXBean proxy =  
  2.      JMX.newMXBeanProxy(mbsc, name, QueueSamplerMXBean.class);  
  3. Sample sample = proxy.getSample();  
  4. Date sampleDate2 = sample.getDate();  
  5. System.out.println("sampleDate2 = " + sampleDate2);   
 

这跟标准MBean的区别就是JMX.newMXBeanProxy()。

 

那这样的话,标准MBean和MXBean不就没有区别了吗?都是要在客户端使用对象接口来获得proxy对象,调用的时候需要的类也需要,这些都要加到客户端的类路径里面。如果这样使用,确实在使用上,两种类型感觉没什么区别。只是在JMX内部,对于MXBean类型,对象是先转换成CompositeData,然后通过网络传输到客户端,客户端再把它转换成自己的bean类型。这些转换都是自动的,根据bean里面的@ConstructorProperties({"date", "size", "head"})转换。

 

所以说,MXbeans为用户提供了在无法得到被调用的接口类型和对象类时,只要我们知道它提供的属性数据的结构,也可以得到里面的数据的功能。而且,MXbean提供了非常多的MXBean,例如用于JVM监控的。在做系统监程序的时候,非常有用。 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值