@Documented @Retention(value=RUNTIME) @Target(value=TYPE) public @interface MXBean
注释标记接口明确作为一个MXBean接口,或不是一个MXBean接口。默认情况下,接口是一个MXBean接口如果是公的和它的名字MXBean结束,在SomethingMXBean。下列接口MXBean接口:
公共接口whatsitmxbean { }@ MXBean公共接口whatsit1interface { }@ MXBean(真的)公共接口whatsit2interface { }
下面的接口不MXBean接口:
接口nonpublicinterfacenotmxbean { }公共接口whatsit3interface { }@ MXBean(假)公共接口misleadingmxbean { }
的MXBean的概念提供了一个简单的方法来编码的MBean仅引用一组预定义的类型,定义的javax.management.openmbean的。这样,你可以确信你的MBean将任何客户端可以使用,包括远程客户,不要求客户端访问模型类的代表你的MBeans类型。
的概念更容易理解与标准MBean概念的比较。这是怎样的一个管理对象可以被表示为一个标准MBean,作为MXBean:
| Standard MBean | MXBean |
|---|---|
public interface MemoryPoolMBean {
String getName();
MemoryUsage getUsage();
// ...
}
|
public interface MemoryPoolMXBean {
String getName();
MemoryUsage getUsage();
// ...
}
|
正如你所看到的,定义是非常相似的。唯一不同的是,命名的接口约定是使用SomethingMXBean为mxbeans,而不是标准MBean SomethingMBean。
在这个管理对象,有一个属性叫做型MemoryUsage Usage。像这样的一个属性的点是它给出了一个数据项集的一致的快照。例如,它可能包括内存池中使用的内存量,以及内存池的当前最大值。如果这些都是单独的项目,单独getAttribute电话获得的,那么我们可以看到在不同的时间是不一致的价值观。我们可能会used值大于max价值。
所以,我们可以这样定义MemoryUsage:
| 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
@ConstructorProperties({"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(尽管它可以)。另一方面,我们增加了一个@ConstructorProperties标注参数的构造函数链接到相应的干将。我们会看到更多关于下面的。
MemoryUsage是一个模型类。与标准MBean,客户端的MBean服务器无法访问Usage属性如果不了解班级MemoryUsage。假设客户端是一个基于JMX技术通用控制台。然后,控制台将必须配置与模型特定类别的每一个应用程序,它可能连接到。问题更糟糕的是,不是用java语言编写的客户。然后可能没有办法告诉客户什么MemoryUsage看起来像。
这是mxbeans不同于标准MBean。虽然我们定义管理界面几乎完全相同的方式,将特定的MXBean框架模型类标准类的java平台。使用数组和从标准javax.management.openmbean包CompositeData和TabularData类,可以建立任意复杂的数据结构只使用标准的类。
这变得更清晰,如果我们比较这两个模型的客户可能看起来像:
| Standard MBean | MXBean |
|---|---|
String name = (String)
mbeanServer. |
String name = (String)
mbeanServer. |
对于这样的简单类型String属性,代码是相同的。但对于复杂类型的属性,标准MBean的代码需要知道客户端模型的具体类MemoryUsage,而不需要非标类MXBean代码。
这里显示的客户端代码的MXBean客户稍微复杂。但是,如果客户确实知道的模型,这里的接口和类MemoryUsage MemoryPoolMXBean,那么它可以构造一个代理。这是推荐的方式与管理对象当你知道模型之前,无论你使用的是标准MBean或mxbeans:
| Standard MBean | MXBean |
|---|---|
MemoryPoolMBean proxy =
JMX. |
MemoryPoolMXBean proxy =
JMX. |
实现内存池对象的作品同样为标准MBean和mxbeans。
| 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 MBean | MXBean |
|---|---|
{
MemoryPoolMBean pool = new MemoryPool();
mbeanServer. |
{
MemoryPoolMXBean pool = new MemoryPool();
mbeanServer. |
一个MXBean是一种MBean。一个MXBean对象可以在MBean服务器直接注册,也可以作为StandardMBean争论在MBean服务器注册所得的MBean。
当一个物体在MBean服务器使用的MBeanServer接口registerMBean或createMBean方法注册,对象的类进行检测以确定什么类型的MBean是:
DynamicMBean然后MBean是动态MBean。注意这类StandardMBean实现这个接口,那么这种情况适用于标准MBean或MXBean使用类StandardMBean创建。SMXBean哪里S是任何非空的字符串,并没有标注@MXBean(false);和/或@MXBean(true)或只是@MXBean。MemoryPoolMXBean MXBean接口。NotCompliantMBeanException。每一个java类型出现的参数或一个MXBean接口的方法的返回类型必须是可使用下面的规则。此外,参数必须是可重构的定义如下。
试图构建一个不符合上述规则MXBean会产生异常。
相同的命名规则应用于一个MXBean的方法作为标准MBean:
T getN(),哪里T是java类(不void)和N是一个非空的字符串,指定有一个可读的属性称为N。java类型和属性的开放型是由下面的映射规则确定。方法final Class getClass()继承Object时忽视了寻找干将。boolean isN()指定有可读属性调用java类型boolean和开放式SimpleType.Boolean N。void setN(T x)指定有一个可写的属性称为N。java类型和属性的开放型是由下面的映射规则确定。(当然,该参数的名称x无关。)规则和isN getN统称定义getter的概念。对于setN规则定义了一个二传手的概念。
这是一个错误,有两人具有相同的名称,或二者具有相同的名称。如果有一个getter和同一名二传手,然后在T类型必须相同。在这种情况下,属性是读/写。如果只有一个getter或setter,属性为只读或只写的分别。
一个MXBean是一种Open MBean,由javax.management.openmbean包定义。这意味着属性、操作参数和返回值的类型、操作都必须可以使用开放的类型,这是OpenType四标准的子类。mxbeans实现这个java类型映射为开放型。
对于每一个java J型,的MXBean映射由以下信息描述:
z-6ad5625e-6a57—4cf5-926f-7f6dca9cdd35例如,对于java类型List<String>:
List<String>),是ArrayType(1, SimpleType.STRING),表示一个一维数组Strings。List<String>),是String[]。List<String>可以转换为一个String[]使用List.toArray(new String[0])。String[]可以转换为一个List<String>使用Arrays.asList。如果没有映射规则存在派生OpenType(J)J,J不能一个方法参数或返回值在一个MXBean接口的类型。
如果有一种方法将开放数据(J)回来然后我们说J是可重构。在一个MXBean接口所有的方法参数必须是可重构的,因为当MXBean框架调用一个方法需要将这些参数从开放数据(J)在一个由JMX.newMXBeanProxy代理到J.,它是在MXBean接口必须重构方法的返回值。
空值是允许所有java类型和开放型,除了原始java类型,他们是不可能的。当转换型J型开放数据(J)或从型开放数据(J)到J型,空值映射为一个空值。
下表总结了类型映射规则。
| 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。因此,OpenType(long)是SimpleType.LONG,和开放数据(long)是java.lang.Long。
原始类型如long[]数组可以直接表示为开放式。因此,OpenType(long[])是ArrayType.getPrimitiveArrayType(long[].class),和开放数据(long[])是long[]。
在实践中,一个普通的int和Integer,等之间的差异,并没有出现因为在JMX API操作总是java对象,不是原语。然而,不同的是显示数组。
List<e>等)一个List<e>或Set<e>,如List<String>或Set<ObjectName>,映射在相同的方式,相同的元素类型的数组,如String[]或ObjectName[]。
一个SortedSet<e>也映射在相同的方式作为一个e[],但只有活如果E是一个类或接口实现Comparable。因此,一个SortedSet<String>或SortedSet<Integer>兑换,但SortedSet<int[]>或SortedSet<List<String>>不。一个SortedSet实例转换将失败与IllegalArgumentException如果它有一个非空的comparator()。
一个List<e>重建作为一个java.util.ArrayList<e>;一Set<e>作为java.util.HashSet<e>;一SortedSet<e>作为java.util.TreeSet<e>。
Map<k,v>等)一个Map<k,v>或SortedMap<k,v>,例如Map<String,ObjectName>,具有开放式TabularType和映射到一个TabularData。的TabularType有两项称为key和value。开放式的key是OpenType(K),和value开放式OpenType(V)。该TabularType指标单项key。
例如,一个Map<String,ObjectName>的TabularType可能与这样的代码构造:
字符串类型=“java使用java.Map< java.lang.string,javax.管理对象>”;字符串函数= []新字符串[ ] {“键”,“值”};OpenType [ ] opentypes =新的OpenType [ ] { simpletype.string对象},简单类型;compositetype式=新的compositetype(typename,typename,键值,键值,opentypes);tabulartype tabulartype =新的tabulartype(typename,typename,棱型,新的字符串[ ] {“关键”});
这里的typeName由 type name rules以下决定。
一个SortedMap<k,v>是以同样的方式映射,但它只是转换如果K是一个类或接口实现Comparable。因此,一个SortedMap<String,int[]>兑换,但SortedMap<int[],String>不。一个SortedMap实例转换将失败与IllegalArgumentException如果它有一个非空的comparator()。
一个Map<k,v>重建作为一个java.util.HashMap<k,v>;一SortedMap<k,v>作为java.util.TreeMap<k,v>。
TabularData是接口。这是用来表示一个Map<k具体类,v>开放数据TabularDataSupport,或另一个班级实施TabularData序列化为TabularDataSupport。
一个MXBean接口或类型的引用,在一个MXBean接口可以参考另一个MXBean接口,,J. Then opentype(J)是SimpleType.OBJECTNAME和开放数据(J)是ObjectName。
例如,假设你有两个MXBean接口这样:
productmxbean公共接口{公共modulemxbean [ ] getmodules();}ModuleMXBean的公共接口{公共productmxbean getproduct();}
实现ModuleMXBean接口返回的getProduct方法实施ProductMXBean接口的对象。的ModuleMXBean对象和返回的ProductMXBean对象都必须注册在同一mxbeans MBean服务器。
方法ModuleMXBean.getProduct()定义一个属性叫做Product。这个属性的开放式SimpleType.OBJECTNAME,和相应的ObjectName值会根据这个名字引用的ProductMXBean在MBean服务器注册。
如果你让一个ModuleMXBean MXBean代理和调用它的getProduct()方法,代理将MapObjectName回ProductMXBean通过另一个MXBean代理。更正式地说,当一个代理用JMX.newMXBeanProxy(mbeanServerConnection, objectNameX, interfaceX)需要MapobjectNameY回interfaceY MXBean接口,另一个,那么,JMX.newMXBeanProxy(mbeanServerConnection, objectNameY, interfaceY)。实施可能会返回一个代理以前创建的电话使用相同的参数JMX.newMXBeanProxy,或者创建一个新的代理。
反向映射是通过以下改变的ModuleMXBean接口:
ModuleMXBean的公共接口{公共productmxbean getproduct();公共无效盘装产品(productmxbean C);}
该setProduct方法的存在意味着Product属性是读/写。之前,这个属性的值是一个ObjectName。当属性设置,该ObjectName必须转换成ProductMXBean对象,setProduct方法预计。这个对象将为给定的ObjectName在相同的MBean服务器MXBean代理。
如果你让一个ModuleMXBean MXBean代理和调用它的setProduct方法,代理将Map的ProductMXBean争论回ObjectName。这只会如果参数实际上是另一个代理的工作,在同一ProductMXBean MBeanServerConnection。代理可以从另一个代理返回(如ModuleMXBean.getProduct()返回一个ProductMXBean代理);或者它可以有JMX.newMXBeanProxy;或者它可以一直使用Proxy与调用句柄是MBeanServerInvocationHandler或子类的创建。
如果同样的MXBean的是两个不同的ObjectNames下注册,参考,从另一个MXBean MXBean会暧昧。因此,如果一个MXBean对象已在MBean服务器并尝试登记在同一个MBean服务器下注册的名字,结果是一个InstanceAlreadyExistsException。注册相同的MBean对象不只一个名字不一般,特别是因为它没有工作,NotificationBroadcasters MBeans。
给定一个java类或接口,不符合上表中的其他规则的MXBean框架将它映射到一个CompositeType如下。这CompositeType类型名称是由下面的 type name rules确定。
这类研究使用公约above干将。(干将必须公共实例方法。)如果没有吸气剂,吸气剂或如果任何具有类型的不可自由兑换,然后是不可改变的。
如果至少有一个getter和每个吸气剂有可转换的类型,然后OpenType(J)是一项CompositeType每个吸气剂。如果吸气剂
T getName()
然后在
CompositeType项目称为
name具有型OpenType(T)。例如,如果该项目是
String getOwner()
然后项目称为
owner并具有开放式
SimpleType.STRING。如果吸气剂
boolean isName()
然后在
CompositeType项目称为
name和类型
SimpleType.BOOLEAN。
注意,第一个字符(或代码点)被转换为小写的情况下。这是java bean的惯例,而由于历史的原因,不同于标准MBean公约。在一个标准MBean或MXBean接口,方法getOwner定义一个属性叫做Owner,而在java bean或映射CompositeType,方法getOwner定义属性或项目称为owner。
如果两种方法产生相同的名称(例如,getOwner和isOwner,或getOwner和getowner)的类型是不可改变的。
当开启式CompositeType,相应的映射到java类型(开放数据(j))是CompositeData。映射到CompositeData J实例对应的CompositeType只是描述如下。首先,如果该实现的接口CompositeDataView,那么接口的toCompositeData方法来做转换。否则,该CompositeData是通过调用getter每个项目并将其转化为相应的数据类型构造。因此,吸气如
List<String> getNames()
将被映射到一个项目叫“names”和开放式ArrayType(1, SimpleType.STRING)。转换CompositeData称getNames()和转换生成的List<String>成String[]为项目“names”。
CompositeData是接口。这是用来表示一个类型为开放数据是CompositeDataSupport具体类,或另一个班级实施CompositeData序列化为CompositeDataSupport。
CompositeData实例如果开放数据(J)是一个java J型CompositeData,然后实例J可以从CompositeData重建,或不可重构[J].。如果在CompositeData任何项目不可重构,然后是无法重建或。
对于任何给定的J,以下规则咨询以确定如何从CompositeData重建实例[J].。列表中的第一个适用规则是将要使用的规则。
如果J有method
public static j from(CompositeData cd)
那方法来重构J.实例
否则,如果至少有一个与ConstructorProperties诠释公共构造函数,然后其中一个构造函数(不一定总是同一个人)来重构J.每个这样的标注实例必须列出许多字符串的构造函数参数;每个字符串必须叫吸气J对应的属性;和这个吸气的类型必须为相应的构造函数参数相同。有人说,是不是在ConstructorProperties注释提到它是不是一个错误(这可能对应于不需要重建对象的信息)。
J的一个实例是通过适当的改造项目从CompositeData调用构造函数的重建。构造函数被称为将在基于项目实际上在CompositeData目前运行的决定,因为这CompositeData可能来自早期版本的J,不是所有的项目都存在。如果所有的特性在其ConstructorProperties注释命名是目前在CompositeData项目构造函数是适用的。如果没有构造函数是适用的,那么尝试重建J失败。
任何可能的性能组合,它必须是:(一)有没有适用的构造函数,或(b)恰好有一个适用的构造函数,或(c)一个适用的构造函数的名字的一个超集的性质相互适用的构造函数为。(换句话说,不能有歧义,构造函数来选择。)如果这种情况是不是真的,那么不可重构[J].。
否则,如果J有一个公共的无参数构造函数,和J每个吸气型和名字有N个具有相同的名称和类型对应的二传手,然后J的实例是无参数构造函数和制定者构建被称为重建项目从CompositeData恢复值。例如,如果有一个method
public List<String> getNames()
然后还必须有此规则应用method
public void setNames(List<String> names)
。
如果CompositeData来自早期版本的J,有些项目可能不存在。在这种情况下,相应的制定者就不叫。
否则,如果J是一个接口,没有任何方法比其他的干将,J的一个实例是使用Proxy用CompositeData转换支持CompositeDataInvocationHandler构造。
否则,不可重构[J].。
规则2不适用于java SE,不包括java.beans包集简介。当目标运行时,不包括java.beans包,哪里有一个不匹配,编译时和运行时环境,J是一个公共构造函数和ConstructorProperties注释编译,然后J不可重构的除非另一个应用规则。
这里是一个例子显示不同的方式编码类型NamedNumber,由int和String。在每一种情况下,该CompositeType看起来像这样:
CompositeType( "NamedNumber", // typeName "NamedNumber", // description new String[] {"number", "name"}, // itemNames new String[] {"number", "name"}, // itemDescriptions new OpenType[] {SimpleType.INTEGER, SimpleType.STRING} // itemTypes );
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;
}
静态from@ConstructorProperties注释:
public class NamedNumber {
public int getNumber() {return number;}
public String getName() {return name;}
@ConstructorProperties({"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不变性的结果。例如,以下类型不可能是一个属性的类型,因为它指的是自己:
结公共接口{getname()字符串;public int getpriority();公共结 getnext();}
它总是可能重写像这样的递归类型,所以他们不再是递归的。这样做可能需要引入新的类型。例如:
节点列表公共接口{
<结>
getnodes()公示名单;}公共接口节点getname()字符串;public int getpriority();}
结>
一个MXBean是一种开放的MBean。然而,由于兼容性的原因,它不是一个OpenMBeanInfo MBeanInfo。特别是,当类的一个属性,参数,或操作返回值是一个原始类型如int,或是void(用于返回类型),然后将属性,操作参数,或将代表各自的MBeanAttributeInfo,MBeanParameterInfo,或MBeanOperationInfo的getType()或getReturnType()返回原始的名字(“int”等)。虽然上面的映射规则指定的开放数据映射为包裹型(Integer等)。
公共构造函数返回的数组MBeanInfo.getConstructors()的MXBean是MBean服务器直接注册将包含所有的MXBean的公共构造函数。如果类没有公共的MXBean的构造函数不考虑公众。返回一个列表,使用的是StandardMBean MXBean类构造源以同样的方式作为标准MBean。不管如何构建它的构造函数参数MXBean,不受MXBean的映射规则和没有相应的OpenType。
通知类型返回的数组MBeanInfo.getNotifications()的MXBean是MBean服务器直接注册将空如果不实施NotificationBroadcaster MXBean接口。否则,它会在时间的MXBean注册调用NotificationBroadcaster.getNotificationInfo()结果。即使这种方法发生变化的结果,对MBeanInfo.getNotifications()结果不。列表中返回一个MXBean,采用StandardMBean或StandardEmitterMBean类派生以同样的方式作为标准MBean。
所有的MBeanAttributeInfo,MBeanParameterInfo的Descriptor,和MBeanOperationInfo对象包含在MBeanInfo将有一场openType其价值是由上面的映射规则规定的OpenType。所以即使getType()是“int”,getDescriptor().getField("openType")将SimpleType.INTEGER。
每个对象的Descriptor还将有一场originalType是一个字符串类型的java的MXBean接口出现。此字符串的格式在下面的部分Type Names描述。
为MBeanInfo的Descriptor将有一场mxbean其值为字符串“true”。
有时一个方法参数或返回值在一个MXBean未映射的类型T必须表示为一个字符串。如果T是一个非泛型类型,此字符串返回值Class.getName()。否则,它是genericstring值(T),定义如下:
Class.getName()返回的值,例如"int"或"java.lang.String"。"[]"。例如,genericstring(int [])是"int[]",和genericstring(表
<字符串>
[ ] [ ])是
"java.util.List<java.lang.String>[][]"。
字符串>List<String>和genericstring(T)包括:参数化类型的返回的Class.getName()完全合格的名称;左尖括号("<");genericstring(一),是第一个类型参数;如果有二类型参数B则", "(逗号和空格)其次是genericstring(B);右尖括号(">")。注意,如果一个方法返回int[],这将Class.getName()返回的字符串"[I"表示,但如果一个方法返回List<int[]>,这将由字符串"java.util.List<int[]>"代表。
一个问题从java类型映射到开放型信号与OpenDataException。这可能发生在一个MXBean接口进行了分析,例如如果它引用一个类型的java.util.Random没有吸气剂。或者它可能发生在一个实例被转换(从一个MXBean或参数在一个MXBean代理方法的返回值),从SortedSet<String>转换为String[]如果SortedSet有一个非空的Comparator当例子。
从开放的类型映射到java类型的一个问题是一个InvalidObjectException示意。这可能发生在一个MXBean接口进行了分析,例如如果它引用一个类型,无法重建根据上述规则,在上下文中,一个可重构的类型是必需的。或者它可能发生在一个实例被转换(一个参数或返回值的MXBean在MXBean代理的方法),例如从一个字符串枚举没有枚举同名的常数。
根据上下文,这OpenDataException或InvalidObjectException可以包裹在一个例外如RuntimeMBeanException或UndeclaredThrowableException。每一个抛出的例外,条件C将是真实的:“E InvalidObjectException OpenDataException或(如适用),或是e.getCause()”真的。
| Modifier and Type | Optional Element and Description |
|---|---|
boolean |
value
如果注释的界面是一个MXBean接口。
|
Submit a bug or feature
For further API reference and developer documentation, see Java SE Documentation. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.
Copyright © 1993, 2014, Oracle and/or its affiliates. All rights reserved.