控制 Bean 的管理介面

前一節的示例中,您對 bean 的管理介面幾乎沒有控制權。每個匯出的 bean 的所有 public 屬性和方法都分別作為 JMX 屬性和操作公開。為了對匯出 bean 的哪些屬性和方法實際上作為 JMX 屬性和操作公開進行更細粒度的控制,Spring JMX 提供了一個全面且可擴充套件的機制來控制您的 bean 的管理介面。

使用 MBeanInfoAssembler API

在幕後,MBeanExporter 將委託給 org.springframework.jmx.export.assembler.MBeanInfoAssembler API 的實現,該實現負責定義每個公開的 bean 的管理介面。預設實現 org.springframework.jmx.export.assembler.SimpleReflectiveMBeanInfoAssembler 定義了一個管理介面,該介面公開所有公共屬性和方法(如您在前面幾節的示例中所見)。Spring 提供了 MBeanInfoAssembler 介面的兩個額外實現,允許您透過使用源級元資料或任何任意介面來控制生成的管理介面。

使用源級元資料:Java 註解

透過使用 MetadataMBeanInfoAssembler,您可以使用源級元資料為您的 bean 定義管理介面。元資料的讀取由 org.springframework.jmx.export.metadata.JmxAttributeSource 介面封裝。Spring JMX 提供了一個使用 Java 註解的預設實現,即 org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource。您必須使用 JmxAttributeSource 介面的實現例項配置 MetadataMBeanInfoAssembler,以便它正常工作,因為沒有預設值。

要將 bean 標記為匯出到 JMX,您應該使用 @ManagedResource 註解註釋 bean 類。您必須使用 @ManagedOperation 註解註釋您希望作為操作公開的每個方法,並使用 @ManagedAttribute 註解註釋您希望公開的每個屬性。在註釋屬性時,您可以省略 getter 或 setter 的註釋以分別建立只寫或只讀屬性。

@ManagedResource 註解的 bean 必須是公共的,公開操作或屬性的方法也必須是公共的。

以下示例顯示了我們用於建立 MBeanServerJmxTestBean 類的註釋版本。

package org.springframework.jmx;

@ManagedResource(
		objectName="bean:name=testBean4",
		description="My Managed Bean",
		log=true,
		logFile="jmx.log",
		currencyTimeLimit=15,
		persistPolicy="OnUpdate",
		persistPeriod=200,
		persistLocation="foo",
		persistName="bar")
public class AnnotationTestBean {

	private int age;
	private String name;

	public void setAge(int age) {
		this.age = age;
	}

	@ManagedAttribute(description="The Age Attribute", currencyTimeLimit=15)
	public int getAge() {
		return this.age;
	}

	@ManagedAttribute(description="The Name Attribute",
			currencyTimeLimit=20,
			defaultValue="bar",
			persistPolicy="OnUpdate")
	public void setName(String name) {
		this.name = name;
	}

	@ManagedAttribute(defaultValue="foo", persistPeriod=300)
	public String getName() {
		return this.name;
	}

	@ManagedOperation(description="Add two numbers")
	@ManagedOperationParameter(name = "x", description = "The first number")
	@ManagedOperationParameter(name = "y", description = "The second number")
	public int add(int x, int y) {
		return x + y;
	}

	public void dontExposeMe() {
		throw new RuntimeException();
	}

}

在前面的示例中,您可以看到 AnnotationTestBean 類已用 @ManagedResource 註解,並且此 @ManagedResource 註解已配置了一組屬性。這些屬性可用於配置 MBeanExporter 生成的 MBean 的各個方面,並將在後面的Spring JMX 註解中詳細解釋。

agename 屬性都已用 @ManagedAttribute 註解,但在 age 屬性的情況下,只有 getter 方法已註釋。這使得這兩個屬性都作為託管屬性包含在管理介面中,但 age 屬性是隻讀的。

最後,add(int, int) 方法已用 @ManagedOperation 註解,而 dontExposeMe() 方法沒有。當您使用 MetadataMBeanInfoAssembler 時,這會導致管理介面僅包含一個操作 (add(int, int))。

AnnotationTestBean 類不需要實現任何 Java 介面,因為 JMX 管理介面完全來自注解。

以下配置顯示瞭如何配置 MBeanExporter 以使用 MetadataMBeanInfoAssembler

<beans>

	<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
		<property name="assembler" ref="assembler"/>
		<property name="namingStrategy" ref="namingStrategy"/>
		<property name="autodetect" value="true"/>
	</bean>

	<!-- will create management interface using annotation metadata -->
	<bean id="assembler"
			class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
		<property name="attributeSource" ref="jmxAttributeSource"/>
	</bean>

	<!-- will pick up the ObjectName from the annotation -->
	<bean id="namingStrategy"
			class="org.springframework.jmx.export.naming.MetadataNamingStrategy">
		<property name="attributeSource" ref="jmxAttributeSource"/>
	</bean>

	<bean id="jmxAttributeSource"
			class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/>

	<bean id="testBean" class="org.springframework.jmx.AnnotationTestBean">
		<property name="name" value="TEST"/>
		<property name="age" value="100"/>
	</bean>

</beans>

在前面的示例中,MetadataMBeanInfoAssembler bean 已配置了 AnnotationJmxAttributeSource 類的例項,並透過 assembler 屬性傳遞給 MBeanExporter。這就是利用 Spring 公開的 MBean 的註解驅動管理介面所需的一切。

Spring JMX 註解

下表描述了 Spring JMX 中可用的註解

表 1. Spring JMX 註解
註解 適用於 描述

@ManagedResource

Class 的所有例項標記為 JMX 託管資源。

@ManagedNotification

指示託管資源發出的 JMX 通知。

@ManagedAttribute

方法(僅限 getter 和 setter)

將 getter 或 setter 標記為 JMX 屬性的一半。

@ManagedMetric

方法(僅限 getter)

將 getter 標記為 JMX 屬性,並新增描述符屬性以指示它是一個指標。

@ManagedOperation

方法

將方法標記為 JMX 操作。

@ManagedOperationParameter

方法

為操作引數定義描述。

下表描述了這些註解中可用的一些常用屬性。有關詳細資訊,請查閱每個註解的 Javadoc。

表 2. Spring JMX 註解屬性
屬性 適用於 描述

objectName

@ManagedResource

MetadataNamingStrategy 用於確定託管資源的 ObjectName

描述

@ManagedResource@ManagedNotification@ManagedAttribute@ManagedMetric@ManagedOperation@ManagedOperationParameter

設定資源、通知、屬性、指標或操作的描述。

currencyTimeLimit

@ManagedResource@ManagedAttribute@ManagedMetric

設定 currencyTimeLimit 描述符欄位的值。

defaultValue

@ManagedAttribute

設定 defaultValue 描述符欄位的值。

log

@ManagedResource

設定 log 描述符欄位的值。

logFile

@ManagedResource

設定 logFile 描述符欄位的值。

persistPolicy

@ManagedResource@ManagedMetric

設定 persistPolicy 描述符欄位的值。

persistPeriod

@ManagedResource@ManagedMetric

設定 persistPeriod 描述符欄位的值。

persistLocation

@ManagedResource

設定 persistLocation 描述符欄位的值。

persistName

@ManagedResource

設定 persistName 描述符欄位的值。

name

@ManagedOperationParameter

設定操作引數的顯示名稱。

index

@ManagedOperationParameter

設定操作引數的索引。

使用 AutodetectCapableMBeanInfoAssembler 介面

為了進一步簡化配置,Spring 包含了 AutodetectCapableMBeanInfoAssembler 介面,該介面擴充套件了 MBeanInfoAssembler 介面,以新增對 MBean 資源自動檢測的支援。如果您使用 AutodetectCapableMBeanInfoAssembler 的例項配置 MBeanExporter,則允許它“投票”決定是否將 bean 公開給 JMX。

AutodetectCapableMBeanInfo 介面的唯一實現是 MetadataMBeanInfoAssembler,它投票決定包含任何標記有 ManagedResource 屬性的 bean。在這種情況下,預設方法是使用 bean 名稱作為 ObjectName,這會導致類似於以下內容的配置

<beans>

	<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
		<!-- notice how no 'beans' are explicitly configured here -->
		<property name="autodetect" value="true"/>
		<property name="assembler" ref="assembler"/>
	</bean>

	<bean id="assembler" class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
		<property name="attributeSource">
			<bean class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/>
		</property>
	</bean>

	<bean id="testBean" class="org.springframework.jmx.AnnotationTestBean">
		<property name="name" value="TEST"/>
		<property name="age" value="100"/>
	</bean>

</beans>

請注意,在前面的配置中,沒有將 bean 傳遞給 MBeanExporter。但是,AnnotationTestBean 仍然被註冊,因為它已用 @ManagedResource 註解,並且 MetadataMBeanInfoAssembler 檢測到此並投票決定包含它。這種方法的唯一缺點是 AnnotationTestBean 的名稱現在具有業務意義。您可以透過配置 ObjectNamingStrategy 來解決此問題,如控制您的 Bean 的 ObjectName 例項中所述。您還可以在使用源級元資料:Java 註解中看到一個使用 MetadataNamingStrategy 的示例。

使用 Java 介面定義管理介面

除了 MetadataMBeanInfoAssembler,Spring 還包括 InterfaceBasedMBeanInfoAssembler,它允許您根據介面集合中定義的方法集來限制公開的方法和屬性。

儘管公開 MBean 的標準機制是使用介面和簡單的命名方案,但 InterfaceBasedMBeanInfoAssembler 透過消除對命名約定的需求、允許您使用多個介面以及消除您的 bean 實現 MBean 介面的需求來擴充套件此功能。

考慮以下介面,它用於為我們之前展示的 JmxTestBean 類定義管理介面

public interface IJmxTestBean {

	public int add(int x, int y);

	public long myOperation();

	public int getAge();

	public void setAge(int age);

	public void setName(String name);

	public String getName();

}

此介面定義了作為 JMX MBean 上的操作和屬性公開的方法和屬性。以下程式碼顯示瞭如何配置 Spring JMX 以使用此介面作為管理介面的定義

<beans>

	<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
		<property name="beans">
			<map>
				<entry key="bean:name=testBean5" value-ref="testBean"/>
			</map>
		</property>
		<property name="assembler">
			<bean class="org.springframework.jmx.export.assembler.InterfaceBasedMBeanInfoAssembler">
				<property name="managedInterfaces">
					<value>org.springframework.jmx.IJmxTestBean</value>
				</property>
			</bean>
		</property>
	</bean>

	<bean id="testBean" class="org.springframework.jmx.JmxTestBean">
		<property name="name" value="TEST"/>
		<property name="age" value="100"/>
	</bean>

</beans>

在前面的示例中,InterfaceBasedMBeanInfoAssembler 配置為在為任何 bean 構造管理介面時使用 IJmxTestBean 介面。重要的是要理解,由 InterfaceBasedMBeanInfoAssembler 處理的 bean 不需要實現用於生成 JMX 管理介面的介面。

在前面的情況下,IJmxTestBean 介面用於為所有 bean 構造所有管理介面。在許多情況下,這並不是期望的行為,您可能希望為不同的 bean 使用不同的介面。在這種情況下,您可以透過 interfaceMappings 屬性將 Properties 例項傳遞給 InterfaceBasedMBeanInfoAssembler,其中每個條目的鍵是 bean 名稱,每個條目的值是用於該 bean 的逗號分隔的介面名稱列表。

如果透過 managedInterfacesinterfaceMappings 屬性未指定管理介面,則 InterfaceBasedMBeanInfoAssembler 會反映 bean 並使用該 bean 實現的所有介面來建立管理介面。

使用 MethodNameBasedMBeanInfoAssembler

MethodNameBasedMBeanInfoAssembler 允許您指定要公開給 JMX 作為屬性和操作的方法名稱列表。以下程式碼顯示了一個示例配置

<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
	<property name="beans">
		<map>
			<entry key="bean:name=testBean5" value-ref="testBean"/>
		</map>
	</property>
	<property name="assembler">
		<bean class="org.springframework.jmx.export.assembler.MethodNameBasedMBeanInfoAssembler">
			<property name="managedMethods">
				<value>add,myOperation,getName,setName,getAge</value>
			</property>
		</bean>
	</property>
</bean>

在前面的示例中,您可以看到 addmyOperation 方法作為 JMX 操作公開,而 getName()setName(String)getAge() 作為 JMX 屬性的相應部分公開。在前面的程式碼中,方法對映適用於公開給 JMX 的 bean。為了在逐個 bean 的基礎上控制方法公開,您可以使用 MethodNameMBeanInfoAssemblermethodMappings 屬性將 bean 名稱對映到方法名稱列表。

© . This site is unofficial and not affiliated with VMware.