Module  java.management
软件包  javax.management

Annotation Type MXBean



  • @Documented
    @Retention(RUNTIME)
    @Target(TYPE)
    public @interface MXBean

    用于将界面明确标记为MXBean接口或不作为MXBean接口的注释。 默认情况下,接口是MXBean接口,如果它是公共的,其名称以MXBean ,如SomethingMXBean 。 以下接口是MXBean接口:

      public interface WhatsitMXBean {}
    
        @MXBean
        public interface Whatsit1Interface {}
    
        @MXBean(true)
        public interface Whatsit2Interface {} 

    以下接口不是MXBean接口:

      interface NonPublicInterfaceNotMXBean{}
    
        public interface Whatsit3Interface{}
    
        @MXBean(false)
        public interface MisleadingMXBean {} 

    MXBean规范

    MXBean概念提供了一种简单的方法来编写仅引用预定义类型的MBean,由javax.management.openmbean定义的类型 。 这样,您可以确保您的MBean可以由任何客户端(包括远程客户端)使用,无需客户端访问代表您的MBean类型的模型特定类 。

    与标准MBean概念相比,这些概念更容易理解。 以下是管理对象如何表示为标准MBean以及MXBean:

    Standard Bean vs. MXBean Standard MBean MXBean
    public interface MemoryPoolMBean {
        String getName();
        MemoryUsage getUsage();
        // ...
    }
              
    public interface MemoryPoolMXBean {
        String getName();
        MemoryUsage getUsage();
        // ...
    }
              

    你可以看到,这些定义非常相似。 唯一的区别是,命名接口的惯例是使用SomethingMXBean作为SomethingMXBean ,而不是SomethingMBean的标准MBean。

    在这个管理对象中,有一个名为Usage的属性类型为MemoryUsage的属性。 像这样的属性的点是它给出了一组数据项的一致的快照。 例如,它可能包括内存池中当前使用的内存量以及内存池的当前最大值。 如果这些是单独的项目,通过单独的getAttribute调用获得,那么我们可以得到在不同时间看不一致的值。 我们可能会得到一个used价值,大于max价值。

    所以我们可以这样定义MemoryUsage :

    Standard Bean vs. MXBean Standard MBean MXBean
    public class MemoryUsage implements Serializable {
        // standard JavaBean conventions with getters
    
        public MemoryUsage(long init, long used,
                           long committed, long max) {...}
        long getInit() {...}
        long getUsed() {...}
        long getCommitted() {...}
        long getMax() {...}
    }
              
    public class MemoryUsage {
        // standard JavaBean conventions with getters
        @ConstructorParameters({"init", "used", "committed", "max"})
        public MemoryUsage(long init, long used,
                           long committed, long max) {...}
        long getInit() {...}
        long getUsed() {...}
        long getCommitted() {...}
        long getMax() {...}
    }
              

    在两种情况下,定义是相同的,除了使用MXBean, MemoryUsage不再需要标记为Serializable (尽管可以)。 另一方面,我们添加了一个@ConstructorParameters注释来将构造函数参数链接到相应的getter。 我们将在下面看到更多的内容。

    MemoryUsage是一个模型特定的类 。 使用标准MBean,如果不知道类MemoryUsage ,则MBean服务器的客户端无法访问Usage属性。 假设客户端是基于JMX技术的通用控制台。 那么控制台必须配置它可能连接到的每个应用程序的特定于模型的类。 对于不是用Java语言编写的客户端,问题更加严重。 那么可能没有办法告诉客户MemoryUsage是什么样的。

    这是MXBeans与标准MBeans不同的地方。 虽然我们以几乎完全相同的方式定义了管理界面,但MXBean框架将特定于类的类转换为Java平台中的标准类。 使用阵列和标准javax.management.openmbean包中的CompositeData和TabularData类,可以使用标准类来构建任意复杂的数据结构。

    如果我们比较两个模型的客户端可能是什么样子,这将变得更加清晰

    Standard Bean vs. MXBean Standard MBean MXBean
    String name = (String)
        mbeanServer.getAttribute(objectName, "Name");
    MemoryUsage usage = (MemoryUsage)
        mbeanServer.getAttribute(objectName, "Usage");
    long used = usage.getUsed();
              
    String name = (String)
        mbeanServer.getAttribute(objectName, "Name");
    CompositeData usage = (CompositeData)
        mbeanServer.getAttribute(objectName, "Usage");
    long used = (Long) usage.get("used");
              

    对于类似String简单类型的属性,代码是一样的。 但是对于具有复杂类型的属性,标准MBean代码要求客户端知道特定于型号的类别MemoryUsage ,而MXBean代码不需要非标准类。

    这里显示的客户端代码对于MXBean客户端来说稍微复杂一些。 但是,如果客户端其实是知道该模型,这里的接口是MemoryPoolMXBean和类MemoryUsage ,那么它可以构造一个代理 。 当您事先知道模型时,无论您使用的是标准MBean还是MXBean,这是建议与受管对象进行交互的方式:

    Standard Bean vs. MXBean Standard MBean MXBean
    MemoryPoolMBean proxy =
        JMX.newMBeanProxy(
            mbeanServer,
            objectName,
            MemoryPoolMBean.class);
    String name = proxy.getName();
    MemoryUsage usage = proxy.getUsage();
    long used = usage.getUsed();
              
    MemoryPoolMXBean proxy =
        JMX.newMXBeanProxy(
            mbeanServer,
            objectName,
            MemoryPoolMXBean.class);
    String name = proxy.getName();
    MemoryUsage usage = proxy.getUsage();
    long used = usage.getUsed();
              

    实现MemoryPool对象与标准MBean和MXBean类似。

    Standard Bean vs. MXBean Standard MBean MXBean
    public class MemoryPool
            implements MemoryPoolMBean {
        public String getName() {...}
        public MemoryUsage getUsage() {...}
        // ...
    }
              
    public class MemoryPool
            implements MemoryPoolMXBean {
        public String getName() {...}
        public MemoryUsage getUsage() {...}
        // ...
    }
              

    在这两种情况下,在MBean服务器中注册MBean的工作原理都是相同的:

    Standard Bean vs. MXBean Standard MBean MXBean
    {
        MemoryPoolMBean pool = new MemoryPool();
        mbeanServer.registerMBean(pool, objectName);
    }
              
    {
        MemoryPoolMXBean pool = new MemoryPool();
        mbeanServer.registerMBean(pool, objectName);
    }
              

    MXBean的定义

    MXBean是一种MBean。 MXBean对象可以直接注册到MBean服务器中,也可以用作StandardMBean的参数,并在MBean服务器中注册MBean。

    当一个对象在MBean服务器使用注册registerMBean或者createMBean的方法MBeanServer接口,该对象的类的检查,以确定是什么类型的MBean:

    • 如果类实现接口DynamicMBean,则MBean是动态MBean。 请注意,类StandardMBean实现此接口,因此本例适用于使用类别StandardMBean创建的标准MBean或MXBean。
    • 否则,如果类与标准MBean命名约定匹配,则MBean是标准MBean。
    • 否则,它可能是一个MXBean。 检查由对象实现的一组接口,用于以下接口:
      • 有一个类名SMXBean其中S是任何非空字符串,并没有注释@MXBean(false) ; 和/或
      • 有注释@MXBean(true)或仅@MXBean 。
      如果只有一个这样的接口,或者如果有一个这样的接口是所有其他接口的子接口,则对象是MXBean。 该界面是MXBean界面 。 在上面的例子中,MXBean接口是MemoryPoolMXBean 。
    • 如果不符合这些条件,则MBean无效,尝试注册它将生成NotCompliantMBeanException 。

    在MXBean界面中显示为方法参数或返回类型的每种Java类型都必须使用以下规则进行转换 。 另外,参数必须如下所述重构 。

    尝试构造不符合上述规则的MXBean将产生异常。

    命名约定

    相同的命名约定应用于MXBean中的方法,如标准MBean中所示:

    1. 方法T getN() ,其中T是Java类型(不是void ),并且N是非空字符串,指定存在称为N的可读属性。 属性的Java类型和Open类型由下面的映射规则确定。 该方法final Class getClass()继承自Object查找获取时被忽略。
    2. 方法boolean isN()指定存在具有Java类型boolean和打开类型SimpleType.Boolean称为N的可读属性。
    3. 方法void setN(T x)指定存在称为N的可写属性。 属性的Java类型和Open类型由下面的映射规则确定。 (当然这个参数的名称是x是无关紧要的)
    4. 每个其他方法都指定有一个与该方法名称相同的操作。 返回值和每个参数的Java类型和Open类型由以下映射规则确定。

    getN和isN的规则共同定义了吸气剂的概念。 setN的规则定义了设置者的概念。

    这是一个错误,有两个同名的getter,或两个同名的setter。 如果有同一个名字的getter和setter,那么两者中的类型T必须相同。 在这种情况下,属性是读/写。 如果只有一个getter或只有一个setter,那么该属性是分别只读或只写的。

    键入映射规则

    MXBean是一种开放的MBean,由javax.management.openmbean包定义。 这意味着属性,操作参数和操作返回值的类型都必须使用Open Types (即OpenType的四个标准子类)来描述 。 MXBeans通过将Java类型映射到“打开类型”来实现此目的。

    对于每个Java类型J ,MXBean映射由以下信息描述:

    • 相应的Open Type, opentype(J) 。 这是一个OpenType的子类的实例 。
    • 映射的 Java类型, opendata(J) ,对于任何给定的opentype(J)来说都是相同的。 这是一个Java类。
    • 如何将值从类型J转换为类型opendata(J) 。
    • 如何将值从类型opendata(J)转换为类型J (如果可以)。

    例如,对于Java类型List<String> :

    • 开放型,OpenType字体( List<String> ),是ArrayType (1, SimpleType.STRING ) ,代表的1维阵列String秒。
    • 映射的Java类型, List<String> ( List<String> )是String[] 。
    • A List<String>可以转换为String[]使用List.toArray(new String[0]) 。
    • 甲String[]可以被转换为一个List<String>使用Arrays.asList 。

    如果没有映射规则从J导出opentype(J) ,则J不能是MXBean接口中的方法参数或返回值的类型。

    如果有一种方法将opendata(J)转换回J,那么我们说J是可重构的 。 MXBean界面中的所有方法参数必须可重构,因为当MXBean框架正在调用方法时,需要将这些参数从opendata(J)转换为J。 在由JMX.newMXBeanProxy生成的代理中,MXBean接口中方法的返回值必须可重构。

    所有Java类型和开放类型都允许空值,除了不可能的原始Java类型。 当从类型J转换为类型opendata(J)或从类型opendata(J)转换为类型J时 ,空值映射到空值。

    下表总结了类型映射规则。

    Type Mapping Rules Java type J opentype(J) opendata(J) int, boolean, etc
    (the 8 primitive Java types) SimpleType.INTEGER,
    SimpleType.BOOLEAN, etc Integer, Boolean, etc
    (the corresponding boxed types) Integer, ObjectName, etc
    (the types covered by SimpleType) the corresponding SimpleType J, the same type int[] etc
    (a one-dimensional array with
    primitive element type) ArrayType.getPrimitiveArrayType(int[].class) etc J, the same type E[]
    (an array with non-primitive element type E; this includes int[][], where E is int[]) ArrayType.getArrayType(opentype(E)) opendata(E)[] List<E>
    Set<E>
    SortedSet<E> (see below) same as for E[] same as for E[] An enumeration E
    (declared in Java as 枚举E {...}) SimpleType.STRING String Map<K,V>
    SortedMap<K,V> TabularType
    (see below) TabularData
    (see below) An MXBean interface SimpleType.OBJECTNAME
    (see below) ObjectName
    (see below) Any other type CompositeType, if possible
    (see below) CompositeData

    以下部分将详细介绍这些规则。

    原始类型的映射

    8种基本Java类型( boolean , byte , short , int , long , float , double , char )被映射到相应的盒装类型从java.lang ,即Boolean , Byte等开放式是相应SimpleType 。 因此, long ( long )是SimpleType.LONG , long ( long )是java.lang.Long 。

    原始类型的数组,如long[]可以直接表示为Open Type。 因此, long[] ( long[] )是ArrayType.getPrimitiveArrayType(long[].class) ,而long[] ( long[] )是long[] 。

    实际上,平滑的int和Integer等之间的区别并不显示,因为JMX API中的操作始终是Java对象而不是基元。 然而,差异确实出现在数组中。

    收藏图( List< E >等)

    A List< E >或Set< E > (例如List<String>或Set<ObjectName>以与相同元件类型的阵列(例如String[]或ObjectName[]相同的方式被映射。

    A SortedSet< E >也以与E []相同的方式进行映射,但如果E是实现Comparable的类或接口,则只能转换。 因此, SortedSet<String>或SortedSet<Integer>是可转换的,但不是SortedSet<int[]>或SortedSet<List<String>> 。 SortedSet实例的转换将失败,如果IllegalArgumentException具有非空值comparator(),则将失败 。

    A List< E >被重建为java.util.ArrayList< E > ; a Set< E > as a java.util.HashSet< E > ; a SortedSet< E > as a java.util.TreeSet< E > 。

    地图映射( Map< K , V >等)

    A Map< K , V >或SortedMap< K , V > ,例如Map<String,ObjectName> ,具有开放类型TabularType并被映射到TabularData 。 TabularType有两个项目叫做key和value 。 key的开放类型为key (K) , value的开放类型为value (V) 。 TabularType的指数是单项key 。

    例如, TabularType的Map<String,ObjectName>可能用这样的代码构建:

      String typeName =
        "java.util.Map<java.lang.String, javax.management.ObjectName>";
    String[] keyValue =
        new String[] {"key", "value"};
    OpenType[] openTypes =
        new OpenType[] {SimpleType.STRING, SimpleType.OBJECTNAME};
    CompositeType rowType =
        new CompositeType(typeName, typeName, keyValue, keyValue, openTypes);
    TabularType tabularType =
        new TabularType(typeName, typeName, rowType, new String[] {"key"}); 

    该typeName这里被确定type name rules详述如下。

    A SortedMap< K , V >以相同的方式映射,但如果K是实现Comparable的类或接口,则只能转换。 因此,一个SortedMap<String,int[]>是可转换的,但是一个SortedMap<int[],String>不是。 一个SortedMap实例的转换将失败,一个IllegalArgumentException如果它有一个非空的comparator() 。

    A Map< K , V >被重建为java.util.HashMap< K , V > ; a SortedMap< K , V > as a java.util.TreeMap< K , V > 。

    TabularData是一个接口。 用于表示Map< K , V >作为开放数据的具体类是TabularDataSupport ,或另一个实现TabularData类,序列化为TabularDataSupport 。

    用于MXBean接口的映射

    MXBean接口或MXBean接口中引用的类型可以引用另一个MXBean接口J。 那么SimpleType.OBJECTNAME (J)是SimpleType.OBJECTNAME , SimpleType.OBJECTNAME (J)是ObjectName 。

    例如,假设您有两个MXBean接口,如下所示:

      public interface ProductMXBean {
        public ModuleMXBean[] getModules();
    }
    
    public interface ModuleMXBean {
        public ProductMXBean getProduct();
    } 

    实现ModuleMXBean接口的对象从其getProduct方法返回一个实现ProductMXBean接口的对象。 ModuleMXBean对象和返回的ProductMXBean对象都必须在同一MBean服务器中注册为MXBean。

    方法ModuleMXBean.getProduct()定义了一个称为Product的属性。 此属性的打开类型为SimpleType.OBJECTNAME ,相应的ObjectName值将是引用的ProductMXBean在MBean服务器中注册的名称。

    如果您为ModuleMXBean创建MXBean代理,并调用其getProduct()方法,则代理将通过创建另一个MXBean代理将ObjectName映射回ProductMXBean 。 更正式地,当一个代理人用JMX.newMXBeanProxy(mbeanServerConnection, objectNameX, interfaceX)进行映射时,需要将objectNameY映射到interfaceY ,另一个MXBean接口,它与JMX.newMXBeanProxy(mbeanServerConnection, objectNameY, interfaceY) 。 该实现可能返回以前通过调用具有相同参数的JMX.newMXBeanProxy创建的代理,或者可能会创建一个新的代理。

    对ModuleMXBean接口进行以下更改说明了反向映射:

      public interface ModuleMXBean {
        public ProductMXBean getProduct();
        public void setProduct(ProductMXBean c);
    } 

    现在setProduct方法的存在意味着Product属性是读/写。 如前所述,此属性的值为ObjectName 。 当属性设置时, ObjectName必须转换为setProduct方法期望的ProductMXBean对象。 该对象将是同一MBean服务器中给定的ObjectName的MXBean代理。

    如果您为ModuleMXBean创建MXBean代理并调用其setProduct方法,则代理将将其ProductMXBean参数映射到ObjectName 。 这只有在参数实际上是另一个代理ProductMXBean ,对于同一个ProductMXBean中的MBeanServerConnection 。 该代理可以从另一个代理返回(如ModuleMXBean.getProduct() ,它为ProductMXBean返回一个代理); 或者它可以由JMX.newMXBeanProxy创建; 或者它可以使用Proxy创建,其中一个调用处理程序是MBeanServerInvocationHandler或一个子类。

    如果相同的MXBean在两个不同的ObjectName下注册,那么来自另一个MXBean的MXBean的引用将是不明确的。 因此,如果MXBean对象已在MBean服务器中注册,并尝试以另一个名称将其注册到同一个MBean服务器中,则结果为InstanceAlreadyExistsException 。 一般不建议在同一个名称下注册同一个MBean对象,特别是因为对于NotificationBroadcaster的MBean来说,它不能正常工作。

    其他类型的映射

    给定一个与上表中其他规则不匹配的Java类或接口J ,MXBean框架将尝试将其映射到CompositeType ,如下所示。 该CompositeType的类型名称由下面的type name rules决定。

    使用约定above检查吸烟者的课程 。 (Getters必须是公共实例方法。)如果没有getter,或者如果任何getter的类型不可转换,则J不可转换。

    如果至少有一个吸气剂和每个吸气剂都有可转换型,那么CompositeType (J)是一个CompositeType ,每个吸气剂都有一个项目。 如果吸气剂是

    T getName()
    那么CompositeType的项目称为name并且具有类型name (T) 。 例如,如果项目是
    String getOwner()
    那么该项目称为owner并具有打开类型SimpleType.STRING 。 如果吸气剂是
    boolean isName()
    那么CompositeType的项目称为name ,并且类型为SimpleType.BOOLEAN 。

    请注意,第一个字符(或代码点)转换为小写。 这遵循Java Beans约定,由于历史原因与标准MBean约定不同。 在标准MBean或MXBean接口中,方法getOwner定义了一个称为Owner的属性,而在Java Bean或映射的CompositeType ,方法getOwner定义了一个名为owner的属性或项目。

    如果两种方法产生相同的项目名称(例如, getOwner和isOwner或getOwner和getowner ),则该类型不可转换。

    当Open Type为CompositeType ,对应的映射Java类型( opendata (J) )为CompositeData 。 对应于刚刚描述的CompositeType从J实例到CompositeData的映射完成如下。 首先,如果J实现接口CompositeDataView ,那么该接口的toCompositeData方法被调用来进行转换。 否则,通过为每个项目调用getter并将其转换为相应的Open Data类型来构建CompositeData 。 因此,吸气剂如

    List<String> getNames()

    将被映射到名称为“ names ”的项目,并打开类型ArrayType(1, SimpleType.STRING) 。 转换为CompositeData将致电getNames() ,并将结果List<String>转换为String[]的项目“ names ”。

    CompositeData是一个接口。 用于表示打开数据类型的具体类是CompositeDataSupport ,或另一个实现CompositeData类,序列化为CompositeDataSupport 。

    从CompositeData重构Java类型J的CompositeData

    如果对于Java类型J , CompositeData (J)是CompositeData ,则可以从CompositeData重构J的一个实例,或者J不可重建。 如果CompositeData中的任何项目不可重构,那么J也不是可重构的。

    对于任何给定的J ,请参考以下规则来确定如何从CompositeData重建J的实例。 列表中的第一个适用规则是将被使用的规则。

    1. 如果J有一个方法
      public static J from(CompositeData cd)
      那么该方法被调用来重建J的一个实例。

    2. 否则,如果J具有至少一个具有@javax.management.ConstructorParameters或@java.beans.ConstructoProperties注释的公共构造函数, 则将 @java.beans.ConstructoProperties其中一个构造函数(不一定总是相同的)来重构J的实例。 如果构造既与注释@javax.management.ConstructorParameters和@java.beans.ConstructorProperties , @javax.management.ConstructorParameters将被使用,并@java.beans.ConstructorProperties将被忽略。 每个这样的注释必须列出与构造函数具有参数一样多的字符串; 每个字符串必须命名一个对应于J的getter的属性; 并且该getter的类型必须与相应的构造函数参数相同。 在@ConstructorParameters或@ConstructorProperties注释中没有提及的吸气剂不是错误(这些可能对应于不需要重建对象的信息)。

      通过从CompositeData调用具有适当重建项目的构造函数来重建J的一个实例。 被调用的构造函数将根据CompositeData实际存在的项目在运行时确定,因为该CompositeData可能来自较早版本的J ,其中并不是所有的项目都存在。 如果其@ConstructorParameters或@ConstructorProperties注释中命名的所有属性作为CompositeData项目存在,则构造函数适用 。 如果不适用构造函数,则重建J的尝试失败。

      对于任何可能的属性组合,必须是(a)没有适用的构造函数,或(b)只有一个适用的构造函数,或(c)其中一个适用的构造函数命名属性的正确超集由其他适用的构造函数命名。 (换句话说,对于哪个构造函数来说绝对不应该有歧义)。如果这个条件不是真的,那么J不可重构。

    3. 否则,如果J有一个public no-arg构造函数,并且对于类型为T和N的 J中的每个getter,都有一个具有相同名称和类型的相应setter,那么J的一个实例使用no-arg构造函数构造,调用者将从CompositeData重建的项目CompositeData恢复值。 例如,如果有一个方法
      public List<String> getNames()
      那么还必须有一种方法
      public void setNames(List<String> names)
      这个规则适用。

      如果CompositeData来自较早版本的J ,某些项目可能不存在。 在这种情况下,不会调用相应的设置器。

    4. 否则,如果J是没有除getter之外的方法的接口,则使用Proxy构建一个J实例,其中CompositeDataInvocationHandler由CompositeData进行转换。

    5. 否则, J不可重构。

    当java.beans.ConstructorProperties不可见时(例如当java.desktop模块不可读或运行时映像不包含java.desktop模块时),规则2不适用。 当定位不包含java.beans包的运行时,并且编译时和运行时间环境之间存在不匹配的地方,其中J使用公共构造函数和ConstructorProperties注释编译时,则除非另有规则适用,否则J不可重构。

    以下是一些示例,显示了由int和String组成的类型NamedNumber不同方式。 在每种情况下, CompositeType如下所示:

    CompositeType(
        "NamedNumber",                      // typeName
        "NamedNumber",                      // description
        new String[] {"number", "name"},    // itemNames
        new String[] {"number", "name"},    // itemDescriptions
        new OpenType[] {SimpleType.INTEGER,
                        SimpleType.STRING}  // itemTypes
    );
          
    1. 静态from方法:
      public class NamedNumber {
          public int getNumber() {return number;}
          public String getName() {return name;}
          private NamedNumber(int number, String name) {
              this.number = number;
              this.name = name;
          }
          public static NamedNumber from(CompositeData cd) {
              return new NamedNumber((Integer) cd.get("number"),
                                     (String) cd.get("name"));
          }
          private final int number;
          private final String name;
      }
                
    2. 公共构造函数与@ConstructorParameters注释:
      public class NamedNumber {
          public int getNumber() {return number;}
          public String getName() {return name;}
          @ConstructorParameters({"number", "name"})
          public NamedNumber(int number, String name) {
              this.number = number;
              this.name = name;
          }
          private final int number;
          private final String name;
      }
                
    3. 每个吸气剂的设定者:
      public class NamedNumber {
          public int getNumber() {return number;}
          public void setNumber(int number) {this.number = number;}
          public String getName() {return name;}
          public void setName(String name) {this.name = name;}
          public NamedNumber() {}
          private int number;
          private String name;
      }
                
    4. 仅与吸气口接口:
      public interface NamedNumber {
          public int getNumber();
          public String getName();
      }
                

    通常情况下,简单地表示数据集不变的类更好。 一个不可变类的实例在构造完成后不能被改变。 请注意, CompositeData本身是不可变的。 不可变性有很多优点,特别是在线程安全和安全方面。 因此,如果可能,通常应避免使用设置器的方法。

    递归类型

    递归(自引用)类型不能在MXBean接口中使用。 这是CompositeType的不变性的结果 。 例如,以下类型不能是属性的类型,因为它引用自身:

      public interface Node {
        public String getName();
        public int getPriority();
        public Node getNext();
    } 

    总是可以重写这样的递归类型,所以它们不再是递归的。 这样做可能需要引入新的类型。 例如:

      public interface NodeList {
        public List<Node> getNodes();
    }
    
    public interface Node {
        public String getName();
        public int getPriority();
    } 

    MXBean的MBeanInfo内容

    MXBean是一种Open MBean。 但是,出于兼容性原因,其MBeanInfo不是OpenMBeanInfo 。 特别地,当属性,参数或操作返回值的类型是基本类型(如int )或void (对于返回类型)时,属性,参数或操作将分别由MBeanAttributeInfo表示, MBeanParameterInfo ,或MBeanOperationInfo其getType()或getReturnType()返回原始名称( “ int ”等)。 是这样的话,即使上述的映射规则指定opendata映射是包装类型( Integer等)。

    对于直接在MBean Server中注册的MXBean, MBeanInfo.getConstructors()返回的公共构造函数数组将包含该MXBean的所有公共构造函数。 如果MXBean的类不是公开的,那么它的构造函数也不被认为是公开的。 为使用StandardMBean类构造的MXBean返回的列表与标准MBean的方法相同。 不管MXBean如何构造,其构造函数参数不受MXBean映射规则的约束,也没有相应的OpenType 。

    如果MXBean不实现NotificationBroadcaster接口,那么直接在MBean Server中注册的MXBean的MBeanInfo.getNotifications()返回的通知类型数组将为空。 否则,将在MXBean注册时拨打NotificationBroadcaster.getNotificationInfo()的结果。 即使这种方法的结果随后变化, MBeanInfo.getNotifications()的结果也不会。 为使用StandardMBean或StandardEmitterMBean类构造的MXBean返回的列表与标准MBean的方法相同。

    该Descriptor对于所有的MBeanAttributeInfo , MBeanParameterInfo和MBeanOperationInfo包含在对象MBeanInfo将有一个字段openType ,其值是OpenType由上述映射规则指定。 所以即使getType()是“ int ”, getDescriptor().getField("openType")将是SimpleType.INTEGER 。

    每个这些对象的Descriptor也将有一个字段originalType ,它是一个字符串,表示MXBean界面中出现的Java类型。 此字符串的格式在下面的Type Names中进行了描述。

    Descriptor为MBeanInfo将有一个字段mxbean的值是字符串“ true ”。

    键入名称

    有时,MXBean中的方法参数或返回值的未映射类型T必须用字符串表示。 如果T是非泛型类型,则此字符串是由Class.getName()返回的值。 否则它是通用字符串(T)的值,定义如下:

    • 如果T是非泛型非数组类型,则通用 字符串 (T)是由Class.getName()返回的值,例如"int"或"java.lang.String" 。
    • 如果T是数组E [] , 通用 "[]" (T)是通用 "[]" (E),后跟"[]" 。 例如, 通用int[] ( int[] )是"int[]" , 通用List<String>[][] ( List<String>[][] )是"java.util.List<java.lang.String>[][]" 。
    • 否则, T是一个参数化类型,如List<String>和genericstring(T)由以下内容组成:由Class.getName()返回的参数化类型的全限定名; 左角支架( "<" ); 通用字符串(A)其中A是第一个类型的参数; 如果有第二个类型参数B,那么", " (一个逗号和一个空格),后跟通用 ", " (B) ; 一个直角括号( ">" )。

    需要注意的是,如果一个方法返回int[] ,这将是用字符串表示"[I"由归国Class.getName() ,但如果方法返回List<int[]> ,这将由字符串来表示"java.util.List<int[]>" 。

    例外

    使用OpenDataException表示从 Java类型映射到 Open类型的问题 。 当分析MXBean接口时,可能会发生这种情况,例如,如果它引用了一个类型,如java.util.Random ,没有getter。 或者,它可以从转换时当一个实例被转换(返回值从一个MXBean方法或参数的方法在MXBean代理)发生,例如SortedSet<String>到String[]如果SortedSet具有非空Comparator 。

    使用InvalidObjectException发送 从打开类型映射到 Java类型的问题 。 当分析MXBean接口时,例如,如果在需要可重构类型的上下文中引用了根据上述规则不可重构的类型,则可能会发生这种情况。 或者当实例被转换时(MXBean中的方法的参数或MXBean代理中的方法的返回值),例如,如果不存在具有该名称的枚举常量,则可以从字符串到枚举。

    根据上下文, OpenDataException或InvalidObjectException可能包装在另一个例外,如RuntimeMBeanException或UndeclaredThrowableException 。 对于每一个被抛出的异常,条件C将为真:“e是OpenDataException或InvalidObjectException (根据需要),或C是E的真。 getCause() ”。

    从以下版本开始:
    1.6
    • Optional Element Summary

      Optional Elements  
      Modifier and Type Optional Element 描述
      boolean value
      如果注释的界面是MXBean接口,则为true。
    • Element Detail

      • value

        boolean value
        如果注释的界面是MXBean接口,则为true。
        结果
        如果注释的界面是MXBean接口,则为true。
        Default:
        真正