天天看点

Java SE 6 新特性: JMX 与系统管理(2)Java SE 6 新特性: JMX 与系统管理(2)

Java SE 6 新特性: JMX 与系统管理(2)

  这里的 ServerMonitorBean 又是怎么回事呢?MXBean 规定了标准 MBean 也要实现一个接口,所有向外界公开的方法都要在这个接口中声明。否则,管理 系统就不能从中获得相应的信息。此外,该接口的名字也有一定的规范:即在标准 MBean 类名之后加上“MBean”后缀。若 MBean 的类名叫做 MBeansName 的话,对应的接口就要叫做 MBeansNameMBean。

  对于管理 系统来说,这些在 MBean 中公开的方法,最终会被 JMX 转化成属性(Attribute)、监听(Listener)和调用(Invoke)的概念。如果读者对 Java Bean 有一些了解的话,不难看出,>public long getUpTime() 对应了 Bean 中的一个称为“upTime”的只读属性。

  下面我们就看一个模拟管理 系统的例子:

package standardbeans; 
import javax.management.MBeanServer; 
import javax.management.MBeanServerFactory; 
import javax.management.ObjectName; 
public class Main { 
    private static ObjectName objectName ; 
    private static MBeanServer mBeanServer; 
    public static void main(String[] args) throws Exception{ 
        init(); 
        manage();                
    } 
    private static void init() throws Exception{ 
        ServerImpl serverImpl = new ServerImpl(); 
        ServerMonitor serverMonitor = new ServerMonitor(serverImpl); 
        mBeanServer = MBeanServerFactory.createMBeanServer(); 
        objectName = new ObjectName("objectName:id=ServerMonitor1"); 
        mBeanServer.registerMBean(serverMonitor,objectName);   
    } 
    private static void manage() throws Exception{ 
        Long upTime = (Long) mBeanServer.getAttribute(objectName, 
        "upTime"); 
        System.out.println(upTime); 
    }  
} 
      

  JMX 的核心是 MBServer。Java SE 已经提供了一个默认实现,可以通过 MBServerFactory.createMBeanServer() 获得。每个资源监控者(MBean)一般都会有名称(ObjectName), 登记在 MBServer 内部的一个 Repository 中。注意,这个 ObjectName 对于每一个 MBServer 必须是唯一的,只能对应于一个 MBean。(读者有兴趣的话,可以试着再给 mBeanServer 注册一个同名的 objectName,看看会怎么样。) 上述例子是在 >init() 方法中完成向 MBeanServer 注册工作的。

  在管理过程中,管理 系统并不与资源或者 SubAgent 直接打交道,也就是说,这里不会直接引用到 MBean。而是通过 MBeanServer 的 >getAttribute 方法取得对应 MBean 的属性的。

  动态 MBean

  但是对于很多已有的 SubAgent 实现,其 Coding Convention 并不符合标准 MBean 的要求。重构所有这些 SubAgent 以符合标准 MBean 标准既费力也不实际。JMX 中给出了动态(Dynamic) MBean 的概念,MBServer 不再依据 Coding Convention 而是直接查询动态 MBean 给出的元数据(meta data)以获得 MBean 的对外接口。

package dynamicbeans; 

import javax.management.*; 
import java.lang.reflect.*; 
public class ServerMonitor implements DynamicMBean { 
  
    private final ServerImpl target;     
    private MBeanInfo mBeanInfo;     
         
    public ServerMonitor(ServerImpl target){ 
        this.target = target; 
    } 
     
    //实现获取被管理的 ServerImpl 的 upTime 
    public long upTime(){ 
        return System.currentTimeMillis() - target.startTime; 
    } 

 //javax.management.MBeanServer 会通过查询 getAttribute("Uptime") 获得 "Uptime" 属性值 
    public Object getAttribute(String attribute) throws AttributeNotFoundException,  
  MBeanException, ReflectionException { 
        if(attribute.equals("UpTime")){ 
            return upTime(); 
        } 
        return null; 
    } 
  
 //给出 ServerMonitor 的元信息。   
    public MBeanInfo getMBeanInfo() { 
        if (mBeanInfo == null) { 
            try { 
                Class cls = this.getClass(); 
                //用反射获得 "upTime" 属性的读方法 
                Method readMethod = cls.getMethod("upTime", new Class[0]);  
                //用反射获得构造方法 
                Constructor constructor = cls.getConstructor(new Class[] 
     {ServerImpl.class}); 
                //关于 "upTime" 属性的元信息:名称为 UpTime,只读属性(没有写方法)。 
                MBeanAttributeInfo upTimeMBeanAttributeInfo = new MBeanAttributeInfo( 
                        "UpTime", "The time span since server start", 
                        readMethod, null); 
                //关于构造函数的元信息 
                MBeanConstructorInfo mBeanConstructorInfo = new MBeanConstructorInfo( 
                        "Constructor for ServerMonitor", constructor); 
                //ServerMonitor 的元信息,为了简单起见,在这个例子里, 
                //没有提供 invocation 以及 listener 方面的元信息  
                mBeanInfo = new MBeanInfo(cls.getName(), 
                        "Monitor that controls the server", 
                        new MBeanAttributeInfo[] { upTimeMBeanAttributeInfo }, 
                        new MBeanConstructorInfo[] { mBeanConstructorInfo }, 
                        null, null);                 
            } catch (Exception e) { 
                throw new Error(e); 
            } 

        } 
        return mBeanInfo; 
    } 

    public AttributeList getAttributes(String[] arg0) {         
        return null; 
    } 
         
    public Object invoke(String arg0, Object[] arg1, String[] arg2)  
  throws MBeanException,  
  ReflectionException {         
        return null; 
    } 

    public void setAttribute(Attribute arg0) throws AttributeNotFoundException,  
  InvalidAttributeValueException, MBeanException, ReflectionException { 
        return;         
    } 

    public AttributeList setAttributes(AttributeList arg0) {         
        return null; 
    }    
}