-
@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 MXBeanpublic interface MemoryPoolMBean { String getName(); MemoryUsage getUsage(); // ... }
public interface MemoryPoolMXBean { String getName(); MemoryUsage getUsage(); // ... }
你可以看到,这些定义非常相似。 唯一的区别是,命名接口的惯例是使用
SomethingMXBean
作为SomethingMXBean
,而不是SomethingMBean
的标准MBean。在这个管理对象中,有一个名为
Usage
的属性类型为MemoryUsage
的属性。 像这样的属性的点是它给出了一组数据项的一致的快照。 例如,它可能包括内存池中当前使用的内存量以及内存池的当前最大值。 如果这些是单独的项目,通过单独的getAttribute
调用获得,那么我们可以得到在不同时间看不一致的值。 我们可能会得到一个used
价值,大于max
价值。所以我们可以这样定义
Standard Bean vs. MXBean Standard MBean MXBeanMemoryUsage
: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 MXBeanString 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客户端来说稍微复杂一些。 但是,如果客户端其实是知道该模型,这里的接口是
Standard Bean vs. MXBean Standard MBean MXBeanMemoryPoolMXBean
和类MemoryUsage
,那么它可以构造一个代理 。 当您事先知道模型时,无论您使用的是标准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 MXBeanpublic 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
。
MemoryPoolMXBean
。 - 有一个类名
- 如果不符合这些条件,则MBean无效,尝试注册它将生成
NotCompliantMBeanException
。
在MXBean界面中显示为方法参数或返回类型的每种Java类型都必须使用以下规则进行转换 。 另外,参数必须如下所述重构 。
尝试构造不符合上述规则的MXBean将产生异常。
命名约定
相同的命名约定应用于MXBean中的方法,如标准MBean中所示:
- 方法
T getN()
,其中T
是Java类型(不是void
),并且N
是非空字符串,指定存在称为N
的可读属性。 属性的Java类型和Open类型由下面的映射规则确定。 该方法final Class getClass()
继承自Object
查找获取时被忽略。 - 方法
boolean isN()
指定存在具有Java类型boolean
和打开类型SimpleType.Boolean
称为N
的可读属性。 - 方法
void setN(T x)
指定存在称为N
的可写属性。 属性的Java类型和Open类型由下面的映射规则确定。 (当然这个参数的名称是x
是无关紧要的) - 每个其他方法都指定有一个与该方法名称相同的操作。 返回值和每个参数的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
, etcInteger
,Boolean
, etc
(the corresponding boxed types)Integer
,ObjectName
, etc
(the types covered bySimpleType
) the correspondingSimpleType
J, the same typeint[]
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 includesint[][]
, where E isint[]
)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 interfaceSimpleType.OBJECTNAME
(see below)ObjectName
(see below) Any other typeCompositeType
, 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>
; aSet<
E>
as ajava.util.HashSet<
E>
; aSortedSet<
E>
as ajava.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>
; aSortedMap<
K , V>
as ajava.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的实例。 列表中的第一个适用规则是将被使用的规则。如果J有一个方法
public static
Jfrom(CompositeData cd)
那么该方法被调用来重建J的一个实例。否则,如果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不可重构。
否则,如果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 ,某些项目可能不存在。 在这种情况下,不会调用相应的设置器。否则,如果J是没有除getter之外的方法的接口,则使用
Proxy
构建一个J实例,其中CompositeDataInvocationHandler
由CompositeData
进行转换。否则, 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 );- 静态
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; }
- 公共构造函数与
@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; }
- 每个吸气剂的设定者:
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; }
- 仅与吸气口接口:
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。
-