JavaTM 2 Platform
Standard Ed. 6

javax.management
註釋型別 MXBean


@Documented
@Retention(value=RUNTIME)
@Target(value=TYPE)
public @interface MXBean

顯式地標記某一介面是否為 MXBean 介面的註釋。預設情況下,如果介面的名稱以 MXBean 結尾(如 SomethingMXBean),則該介面為 MXBean 介面。以下介面是 MXBean 介面:

    public interface WhatsitMXBean {}

    @MXBean
    public interface Whatsit1Interface {}

    @MXBean(true)
    public interface Whatsit2Interface {}
    

以下介面不是 MXBean 介面:

    public interface Whatsit3Interface{}

    @MXBean(false)
    public interface MisleadingMXBean {}
    

MXBean 規範

MXBean 概念提供了一種對 MBean 進行編碼的簡單方式,這種方式只參考一組預定義的型別,這些型別由 javax.management.openmbean 定義。使用這種方式可以確保任何客戶端(包括遠端客戶端)都可以使用您的 MBean,無需客戶端具有存取表示 MBean 型別的特定於模型的類別 的權限。

與 Standard MBean 概念相比,這些概念更容易理解一些。以下是將管理物件表示為 Standard MBean 和 MXBean 的方式:

Standard MBeanMXBean
public interface MemoryPoolMBean {
String getName();
MemoryUsage getUsage();
    // ...
}
          
public interface MemoryPoolMXBean {
String getName();
MemoryUsage getUsage();
    // ...
}
          

如您所見,這些定義非常相似。唯一的不同是命名介面的約定將使用 MXBean 的 Something MXBean,而不是 Standard MBean 的 Something MBean

在此管理物件中,有一種型別為 MemoryUsage 的稱作 Usage 的屬性。此類別屬性的要點是,它給出了一組資料項的統一快照。例如,它可能包括記憶體池中目前已使用的記憶體量,以及記憶體池的當前最大量。如果這些是單獨的項(通過單獨的 getAttribute 調用獲得),那麼我們可以在不同時間查看不一致的值。我們可能獲得大於 max 值的 used 值。

因此,可以按如下形式定義 MemoryUsage

Standard MBeanMXBean
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 是一個特定於模型的類別。使用 Standard MBean 時,如果 MemoryUsage 類別對於 MBean Server 的客戶端為未知類別,那麼該客戶端將無法存取 Usage 屬性。假定該客戶端是一個基於 JMX 技術的通用終端機。那麼必須使用該終端機可以連接到的每個應用程序的特定於模型的類別來配置此終端機。對於未用 Java 語言編寫的客戶端,問題甚至更為嚴重。此時可能無法通知客戶端 MemoryUsage 是什麼樣的。

這就是 MXBean 與 Standard MBean 的不同之處。儘管我們以幾乎完全相同的方式定義了管理介面,但 MXBean 框架會從 Java 平臺將特定於模型的類別轉換 為標準類別。使用陣列以及標準 javax.management.openmbean 套件中的 CompositeDataTabularData 類別,就有可能只使用標準類別來建構任意複雜度的資料結構。

如果比較兩種模型的客戶端的外觀,這將變得更清楚:

Standard MBeanMXBean
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)的屬性,程式碼是相同的。但對於具有複雜型別的屬性,Standard MBean 程式碼要求客戶端知道特定於模型的類別 MemoryUsage,而 MXBean 程式碼則不需要任何非標準類別。

此處顯示的客戶端程式碼對於 MXBean 客戶端而言更加複雜。但是,如果客戶端確實知道該模型、此處的介面 MemoryPoolMXBeanMemoryUsage 類別,則該客戶端可以建構一個代理。在預先知道模型的情況下,建議您使用這種方式與管理物件進行交互,不必考慮正在使用的是 Standard MBean 還是 MXBean:

Standard MBeanMXBean
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();
          

對於 Standard MBean 和 MXBean 而言,實作 MemoryPool 物件的方式是類似的。

Standard MBeanMXBean
public class MemoryPool
implements MemoryPoolMBean {
public String getName() {...}
public MemoryUsage getUsage() {...}
    // ...
}
          
public class MemoryPool
implements MemoryPoolMXBean {
public String getName() {...}
public MemoryUsage getUsage() {...}
    // ...
}
          

在兩種情況下,在 MBean Server 中註冊 MBean 的方式是相同的:

Standard MBeanMXBean
{
MemoryPoolMBean pool = new MemoryPool();
mbeanServer.registerMBean(pool, objectName);
}
          
{
MemoryPoolMXBean pool = new MemoryPool();
mbeanServer.registerMBean(pool, objectName);
}
          

MXBean 的定義

MXBean 是一種 MBean。MXBean 物件可以直接在 MBean Server 中註冊,也可以用作在 MBean Server 中註冊的 StandardMBean 和結果 MBean 的參數。

當使用 MBeanServer 介面的 registerMBeancreateMBean 方法在 MBean Server 中註冊某個物件時,要檢查該物件的類別來確定 MBean 的型別:

作為參數出現的每個 Java 型別或 MXBean 介面中某一方法的返回型別在使用下面的規則進行轉換時,必須是可轉換的。此外,參數必須是可重新建構的,正如下面所定義的那樣。

嘗試建構不符合上述規則的 MXBean 將產生一個異常。

命名約定

與在 Standard MBean 中一樣,相同的命名約定可應用於 MXBean 中的各種方法:

  1. 方法 T getN() 明確說明存在一個名為 N 的可讀屬性,該方法中的 T 是一種 Java 型別(不可以為 void),N 為非空(null)字元串。該屬性的 Java 型別和 Open 型別是根據下面的映射規則確定的。在尋找獲取方法時,將忽略從 Object 繼承的方法 final Class getClass()
  2. 方法 boolean isN() 明確說明存在一個名為 N 的可讀屬性,且該屬性的 Java 型別為 boolean,Open 型別為 SimpleType.Boolean
  3. 方法 void setN(T x) 明確說明存在一個名為 N 的可寫屬性。該屬性的 Java 型別和 Open 型別是根據下面的映射規則確定的。(當然,參數的名稱 x 無關緊要。)
  4. 其他每個方法都明確說明存在一個名稱與該方法相同的操作。返回值和每個參數的 Java 型別和 Open 型別是根據下面的映射規則確定的。

getNisN 的規則共同定義了 getter 的概念。setN 的規則定義了 setter 的概念。

兩個獲取方法具有相同名稱或者兩個設置方法具有相同名稱是一種錯誤。如果一個獲取方法和一個設置方法具有相同的名稱,則二者的型別 T 必須相同。在這種情況下,屬性為 read/write。如果只有一個獲取方法或只有一個設置方法,則屬性分別為 read-only 或 write-only。

型別映射規則

MXBean 是一種 Open MBean,由 javax.management.openmbean 套件定義。這意味著屬性型別、操作參數和操作返回值都必須是可以使用 Open Types(即 OpenType 的四個標準子類別)描述的。MXBean 通過將 Java 型別映射為 Open Types 來實作此操作。

對於每個 Java 型別 J,MXBean 映射關係根據以下資訊來描述:

例如,對於 Java 型別 List<String>

如果沒有用來從 J 中派生 opentype(J) 的映射規則,則 J 不能是 MXBean 介面中方法參數或返回值的型別。

如果有辦法將 opendata(J) 轉換回 J,則我們說 J可重新建構的。MXBean 介面中的所有方法參數必須是可重新建構的,這是因為當 MXBean 框架調用某一方法時,它需要將這些參數從 opendata(J) 轉換為 J。在由 JMX.newMXBeanProxy 產生的代理中,MXBean 介面中方法的返回值必須是可重新建構的。

所有 Java 型別和 Open Types 都允許使用 null 值,不可能使用 null 值的一些基本 Java 型別除外。當從型別 J 轉換為型別 opendata(J) 或從型別 opendata(J) 轉換為型別 J 時,null 值被映射為一個 null 值。

下表總結了型別映射規則。

Java 型別 J opentype(J) opendata(J)
intboolean
(8 個基本 Java 型別)
SimpleType.INTEGER
SimpleType.BOOLEAN
IntegerBoolean
(相應的 boxed 型別)
IntegerObjectName
SimpleType 套件含的型別)
相應的 SimpleType J,相同型別
int[]
(具有
基本元素型別的一維陣列)
ArrayType.getPrimitiveArrayType(int[].class) J,相同型別
E[]
(具有非基本元素型別 E 的陣列;這包括 int[][],其中 Eint[]
ArrayType.getArrayType(opentype(E)) opendata(E)[]
List&lt;E&gt;
Set&lt;E&gt;
SortedSet&lt;E&gt;(參見以下內容)
E[] 相同 E[] 相同
列舉 E
(在 Java 中被宣告為 enum E {...}
SimpleType.STRING String
Map&lt;K,V&gt;
SortedMap&lt;K,V&gt;
TabularType
(參見以下內容)
TabularData
(參見以下內容)
MXBean 介面 SimpleType.OBJECTNAME
(參見以下內容)
ObjectName
(參見以下內容)
任何其他型別 CompositeType,如果可能
(參見以下內容)
CompositeData

以下幾節將詳細解釋這些規則。

基本型別的映射

8 種基本 Java 型別(booleanbyteshortintlongfloatdoublechar)都可映射到 java.lang 中的相應 boxed 型別,即 BooleanByte 等。Open Type 是相應的 SimpleType。因此,opentype(long)SimpleType.LONGopendata(long)java.lang.Long

諸如 long[] 之類別的基本型別的陣列可以直接表示為一種 Open Type。因此,openType(long[])ArrayType.getPrimitiveArrayType(long[].class)opendata(long[])long[]

實際上,普通 intInteger 等之間的差異不會顯現出來,因為 JMX API 中的操作總是在 Java 物件上進行,而不是在基本型別上進行。但是,陣列中確實 存在這種差異。

集合的映射(List&lt;E&gt; 等)

List&lt;E&gt;Set&lt;E&gt;(如 List<String>Set<ObjectName>)以相同方式映射為相同元素型別的陣列,如 String[]ObjectName[]

也可以用相同方式將 SortedSet&lt;E&gt; 映射為 E[],但是只有在 E 是實作 Comparable 的類別或介面時,它才是可轉換的。因此,SortedSet<String>SortedSet<Integer> 是可轉換的,但 SortedSet<int[]>SortedSet<List<String>&gt; 是不可轉換的。如果 SortedSet 實例包含一個非 null comparator(),那麼對該實例的轉換將失敗,並拋出 IllegalArgumentException

List&lt;E&gt; 被重新建構為一個 java.util.ArrayList&lt;E&gt;Set&lt;E&gt; 被重新建構為一個 java.util.HashSet&lt;E&gt;SortedSet&lt;E&gt; 被重新建構為一個 java.util.TreeSet&lt;E&gt;

映射的映射關係(Map&lt;K,V&gt; 等)

Map&lt;K,V&gt;SortedMap&lt;K,V&gt;(如 Map<String,ObjectName>)包含 Open Type TabularType,並且可映射為一個 TabularDataTabularType 有兩個稱為 keyvalue 的項。key 的 Open Type 為 opentype(K)value 的 Open Type 為 opentype(V)TabularType 的索引是單個項 key

例如,用於 Map<String,ObjectName>TabularType 可以使用如下程式碼建構:

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 由下面將詳細介紹的型別名稱規則確定。

SortedMap&lt;K,V&gt; 以相同的方式映射,但只有在 K 是實作 Comparable 的類別或介面時才是可轉換的。因此,SortedMap<String,int[]> 是可轉換的,但 SortedMap<int[],String> 是不可轉換的。如果 SortedMap 實例包含一個非 null comparator(),那麼該實例的轉換將失敗,並將拋出 IllegalArgumentException

Map&lt;K,V&gt; 被重新建構為一個 java.util.HashMap&lt;K,V&gt;SortedMap&lt;K,V&gt; 被重新建構為一個 java.util.TreeMap&lt;K,V&gt;

TabularData 是一個介面。用於將 Map&lt;K,V&gt; 表示為 Open Data 的具體類別是 TabularDataSupport,或是實作作為 TabularDataSupport 序列化的 TabularData 的另一個類別。

MXBean 介面的映射

MXBean 介面(或 MXBean 介面中參考的型別)可以參考另一個 MXBean 介面 J。這時 opentype(J)SimpleType.OBJECTNAMEopendata(J)ObjectName

例如,假設您有兩個如下所示的 MXBean 介面:

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

public interface ModuleMXBean {
public ProductMXBean getProduct();
}
    

實作 ModuleMXBean 介面的物件從其 getProduct 方法返回一個實作 ProductMXBean 介面的物件。ModuleMXBean 物件和返回的 ProductMXBean 物件都必須註冊為相同 MBean Server 中的 MXBean。

方法 ModuleMXBean.getProduct() 定義了一個稱為 Product 的屬性。此屬性的 Open Type 為 SimpleType.OBJECTNAME,並且相應的 ObjectName 值將是所參考的 ProductMXBean 在 MBean Server 中註冊的名稱。

如果為 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 屬性為 read/write。與以前一樣,該屬性的值是一個 ObjectName。設置屬性時,必須將 ObjectName 轉換成 setProduct 方法所需要的 ProductMXBean 物件。此物件將是相同 MBean Server 中給定 ObjectName 的 MXBean 代理。

如果為 ModuleMXBean 建構一個 MXBean 代理並調用其 setProduct 方法,則該代理會將其 ProductMXBean 參數映射回 ObjectName。只有在該參數實際上是另一代理時,才能如此操作,這也可用於相同 MBeanServerConnection 中的 ProductMXBean。可以從另一代理(如返回 ProductMXBean 的代理的 ModuleMXBean.getProduct())返回代理;或由 JMX.newMXBeanProxy 創建代理;或使用帶有調用處理程序的 Proxy 創建,該調用處理程序是 MBeanServerInvocationHandler 或一個子類別。

如果相同的 MXBean 在兩個不同的 ObjectName 下註冊,那麼對哪個 MXBean 進行參考將是不明確的。因此,如果某個 MXBean 物件已經在 MBean Server 中註冊並且嘗試在相同 MBean Server 的另一名稱下對其進行註冊,結果將是拋出 InstanceAlreadyExistsException。通常不鼓勵在多個名稱下註冊同一 MBean 物件,因為它顯然不適合那些是 NotificationBroadcaster 的 MBean。

其他型別的映射

如果給定的 Java 類別或介面 J 與上述表中的其他規則不比對,則 MXBean 框架會嘗試按照以下方式將其映射到 CompositeType。此 CompositeType 的型別名稱是根據以下型別名稱規則確定的。

使用上述約定檢查獲取方法的類別。(Getter 必須是公共實例方法。)如果沒有獲取方法,或任何獲取方法都有一個不可轉換的型別,則 J 是不可轉換的。

如果至少有一個獲取方法並且每個獲取方法都有一個可轉換的型別,則 opentype(J) 是一個 CompositeType,它對於每個獲取方法都有一個項。如果獲取方法為

T getName()
CompositeType 中的項被稱為 name,且型別為 opentype(T)。例如,如果該項為
String getOwner()
則該項被稱為 owner,且 Open Type 為 SimpleType.STRING。如果該獲取方法為
boolean isName()
CompositeType 中的項被稱為 name,且型別為 SimpleType.BOOLEAN

注意,第一個字元(或程式碼點)要轉換為小寫。這遵守 Java Bean 約定,由於歷史原因,該約定與 Standard MBean 約定不同。在 Standard MBean 或 MXBean 介面中,方法 getOwner 定義了名為 Owner 的屬性,而在 Java Bean 或映射的 CompositeType 中,方法 getOwner 定義了名為 owner 的屬性或項。

如果兩個方法產生了相同的項名稱(如 getOwnerisOwner,或 getOwnergetowner),則該型別是不可轉換的。

當 Open Type 為 CompositeType 時,相應的映射 Java 型別 (opendata(J)) 是 CompositeData。從 J 的實例到對應於剛描述的 CompositeTypeCompositeData 的映射是按以下方式完成的。首先,如果 J 實作了介面 CompositeDataView,則調用該介面的 toCompositeData 方法來完成轉換。否則,通過對每個項調用獲取方法並將其轉換為相應的 Open Data 型別來建構 CompositeData。因此,如下所示的獲取方法

List<String> getNames()

將被映射到名稱為 "names" 且 Open Type 為 ArrayType(1, SimpleType.STRING) 的項。對 CompositeData 的轉換將調用 getNames(),並將結果 List<String> 轉換為項 "names" 的 String[]

CompositeData 是一個介面。用於將型別表示為 Open Data 的具體類別是 CompositeDataSupport,或者是實作作為 CompositeDataSupport 序列化的 CompositeData 的另一個類別。

CompositeData 重新建構 Java 型別 J 的實例

如果 opendata(J) 是 Java 型別 JCompositeData,則要麼從 CompositeData 重新建構 J 的實例,要麼 J 是不可重新建構的。如果 CompositeData 中的任何項都是不可重新建構的,則 J 也是不可重新建構的。

對於任何給定的 J,都可參考以下規則來確定如何從 CompositeData 重新建構 J 的實例。列表中的第一個適用規則是將被使用的規則。

  1. 如果 J 擁有方法
    public static J from(CompositeData cd)
    ,則調用該方法來重新建構一個 J 實例。

  2. 否則,如果 J 至少有一個帶有 ConstructorProperties 註釋的公共建構子,則將調用這些建構子之一(不一定總是同一個建構子)來重新建構一個 J 實例。每個這樣的註釋都必須列出與建構子的參數數量相同的字元串;每個字元串必須命名一個對應於 J 的獲取方法的屬性;此獲取方法的型別必須與對應建構子參數的型別相同。如果存在 ConstructorProperties 註釋中未提到的獲取方法(這些獲取方法可能對應於重新建構物件所不需要的資訊),這不算是一種錯誤。

    通過使用 CompositeData 中經過適當重新建構的項來調用建構子,可以重新建構一個 J 實例。要調用的建構子將在運行的時候根據實際出現在 CompositeData 中的項來確定,在這種情況下,此 CompositeData 可能來自 J 的較早版本,該版本中沒有包含所有的項。如果在建構子的 ConstructorProperties 註釋中命名的所有屬性都作為項出現在 CompositeData 中,則該建構子是適用的。如果沒有建構子是適用的,則嘗試重新建構 J 將失敗。

    對於任何可能的屬性組合,必須是以下情況:(a) 沒有適用的建構子,或 (b) 恰恰有一個適用的建構子,或 (c) 適用的建構子之一命名了由其他每個適用建構子命名的屬性的適當父集。(換句話說,在選擇建構子時永遠不應該有混淆現象。)如果此條件不為 true,則 J 是不可重新建構的。

  3. 否則,如果 J 具有不帶參數的公共建構子,並且對於型別為 T 且名稱為 NJ 中的每個獲取方法,都有一個具有相同名稱和型別的相應設置方法,則 J 的實例是使用不帶參數的建構子建構的 ,並使用 CompositeData 中經過重新建構的項來調用這些設置方法,以恢復某些值。例如,如果具有方法
    public List<String> getNames()
    ,則還必須有一個應用此規則的方法
    public void setNames(List<String> names)

    如果 CompositeData 來自 J 的較早版本,則有些項可能不會出現。在這種情況下,不會調用相應的設置方法。

  4. 否則,如果 J 是一個除了獲取方法之外沒有其他方法的介面,則使用具有 CompositeDataInvocationHandler(受正在轉換的 CompositeData 支持)的 Proxy 來建構一個 J 實例。

  5. 否則,J 是不可重新建構的。

下面的範例顯示了對那些由 intString 組成的型別 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. 帶有 @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;
    }
              
  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(針對返回型別),則屬性、參數或操作將被分別表示為其 getType()getReturnType() 返回基本名稱("int" 等)的 MBeanAttributeInfoMBeanParameterInfoMBeanOperationInfo。即使上面的映射規則指定 opendata 映射是包裹型別(Integer 等),情況也是這樣。

由直接在 MBean Server 中註冊的 MXBean 的 MBeanInfo.getConstructors() 返回的公共建構子陣列,將包含該 MXBean 的所有公共建構子。如果 MXBean 的類別不是公共類別,則其建構子也被視為非公共建構子。MXBean 的返回列表是使用 StandardMBean 類別建構的,其派生方式與 Standard MBean 的相同。不管 MXBean 是如何建構的,其建構子參數都不服從 MXBean 映射規則,且沒有對應的 OpenType

如果直接在 MBean Server 中註冊的 MXBean 沒有實作 NotificationBroadcaster 介面,則由其 MBeanInfo.getNotifications() 返回的通知型別的陣列將為空。否則,它將是在註冊 MXBean 時調用 NotificationBroadcaster.getNotificationInfo() 的結果。即使此方法的結果以後發生更改,MBeanInfo.getNotifications() 的結果也不會發生更改。MXBean 的返回列表是使用 StandardMBeanStandardEmitterMBean 類別建構的,其派生方式與 Standard MBean 的相同。

MBeanInfo 中包含的所有 MBeanAttributeInfoMBeanParameterInfoMBeanOperationInfo 物件的 Descriptor 都將包含一個欄位 openType,其值為由上述映射規則指定的 OpenType。因此,即使在 getType() 為 "int" 時,getDescriptor().getField(&quot;openType&quot;) 仍將是 SimpleType.INTEGER

每個物件的 Descriptor 還有一個 originalType 欄位,該欄位是一個表示 MXBean 介面中出現的 Java 型別的字元串。此字元串的格式將在下面的型別名稱一節中描述。

MBeanInfoDescriptor 將包含一個 mxbean 欄位,該欄位值是字元串 "true"。

型別名稱

有時必須將 MXBean 中方法參數或返回值的未映射型別 T 表示為一個字元串。如果 T 是非一般型別,則此字元串是由 Class.getName() 返回的值。否則,它是 genericstring(T) 的值,定義方式如下:

注意,如果某一方法返回 int[],則這將由 Class.getName() 返回的字元串 &quot;[I&quot; 表示,但如果某一方法返回 List<int[]>,則這將由字元串 &quot;java.util.List<int[]>&quot; 表示。

異常

Java 型別映射 Open 型別時存在的一個問題是會出現 OpenDataException 信號。這可能發生在分析 MXBean 介面時,例如,如果它參考一個類似於沒有獲取方法的 java.util.Random 的型別。或者發生在轉換實例(將返回值從 MXBean 中的方法或參數轉換為 MXBean 代理中的方法)時,例如在 SortedSet 擁有非 null Comparator 的情況下從 SortedSet<String> 轉換為 String[] 時。

Open 型別映射 Java 型別時存在的一個問題是會出現 InvalidObjectException 信號。這可能發生在分析 MXBean 介面時,例如,當上下文需要可重新建構的型別時,根據上述規則參考了一個不可重新建構的 型別。或者發生在轉換實例(MXBean 中某一方法的參數或 MXBean 代理中某一方法的返回值)時,例如在沒有具備該名稱的 Enum 常數的情況下將 String 轉換為 Enum 時。

根據上下文,OpenDataExceptionInvalidObjectException 可以包裹在另一個異常(如 RuntimeMBeanExceptionUndeclaredThrowableException)中。 對於每個拋出的異常,條件 C 將為 true:"eOpenDataExceptionInvalidObjectException(如果合適),或者 Ce.getCause()" 中為 ture。

從以下版本開始:
1.6

可選元素摘要
 boolean value
          如果被註釋的介面是一個 MXBean 介面,則為 true。
 

value

public abstract boolean value
如果被註釋的介面是一個 MXBean 介面,則為 true。

返回:
如果被註釋的介面是一個 MXBean 介面,則返回 true。
預設值:
true

JavaTM 2 Platform
Standard Ed. 6

提交錯誤或意見

版權所有 2008 Sun Microsystems, Inc. 保留所有權利。請遵守GNU General Public License, version 2 only