Bean の管理インターフェースの制御

前のセクションの例では、Bean の管理インターフェースをほとんど制御できませんでした。エクスポートされた各 Bean のすべての public プロパティとメソッドは、それぞれ JMX 属性と操作として公開されました。エクスポートされた Bean のどのプロパティとメソッドが実際に JMX 属性および操作として公開されるかを正確に細かく制御するために、Spring JMX は Bean の管理インターフェースを制御するための包括的で拡張可能なメカニズムを提供します。

MBeanInfoAssembler インターフェースの使用

背後で、MBeanExporter は org.springframework.jmx.export.assembler.MBeanInfoAssembler インターフェースの実装に委譲します。org.springframework.jmx.export.assembler.MBeanInfoAssembler インターフェースは、公開される各 Bean の管理インターフェースを定義するロールを果たします。デフォルトの実装 org.springframework.jmx.export.assembler.SimpleReflectiveMBeanInfoAssembler は、すべてのパブリックプロパティとメソッドを公開する管理インターフェースを定義します(前のセクションの例で見たように)。Spring は、MBeanInfoAssembler インターフェースの 2 つの追加の実装を提供します。これにより、ソースレベルのメタデータまたは任意のインターフェースを使用して、生成された管理インターフェースを制御できます。

ソースレベルのメタデータの使用: Java アノテーション

MetadataMBeanInfoAssembler を使用することにより、ソースレベルのメタデータを使用して、Bean の管理インターフェースを定義できます。メタデータの読み取りは、org.springframework.jmx.export.metadata.JmxAttributeSource インターフェースによってカプセル化されます。Spring JMX は、Java アノテーション、つまり org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource を使用するデフォルトの実装を提供します。MetadataMBeanInfoAssembler を正しく機能させるには、JmxAttributeSource インターフェースの実装インスタンスを使用して MetadataMBeanInfoAssembler を構成する必要があります(デフォルトはありません)。

Bean を JMX にエクスポートするようにマークするには、Bean クラスに ManagedResource アノテーションを付ける必要があります。ManagedOperation アノテーションを使用して操作として公開する各メソッドをマークし、ManagedAttribute アノテーションを使用して公開する各プロパティをマークする必要があります。プロパティをマークする場合、getter または setter のアノテーションを省略して、それぞれ書き込み専用または読み取り専用の属性を作成できます。

操作または属性を公開するメソッドと同様に、ManagedResource アノテーション付き Bean はパブリックである必要があります。

次の例は、MBeanServer の作成で使用した JmxTestBean クラスのアノテーション付きバージョンを示しています。

package org.springframework.jmx;

import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedAttribute;

@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 implements IJmxTestBean {

	private String name;
	private int age;

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

	public void setAge(int age) {
		this.age = 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 name;
	}

	@ManagedOperation(description="Add two numbers")
	@ManagedOperationParameters({
		@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();
	}

}

上記の例では、JmxTestBean クラスに ManagedResource アノテーションが付けられ、この ManagedResource アノテーションに一連のプロパティが設定されていることがわかります。これらのプロパティは、MBeanExporter によって生成される MBean のさまざまなアスペクトを構成するために使用でき、後でソースレベルのメタデータ型で詳しく説明します。

age プロパティと name プロパティの両方に ManagedAttribute アノテーションが付けられていますが、age プロパティの場合は、getter のみがマークされています。これにより、これらのプロパティの両方が管理インターフェースに属性として含まれますが、age 属性は読み取り専用です。

最後に、add(int, int) メソッドは ManagedOperation 属性でマークされていますが、dontExposeMe() メソッドはマークされていません。これにより、MetadataMBeanInfoAssembler を使用する場合、管理インターフェースには 1 つの操作(add(int, int))のみが含まれます。

次の構成は、MetadataMBeanInfoAssembler を使用するように MBeanExporter を構成する方法を示しています。

<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>

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

	<!-- 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="testBean" class="org.springframework.jmx.AnnotationTestBean">
		<property name="name" value="TEST"/>
		<property name="age" value="100"/>
	</bean>
</beans>

上記の例では、MetadataMBeanInfoAssembler Bean は AnnotationJmxAttributeSource クラスのインスタンスで構成され、アセンブラープロパティを介して MBeanExporter に渡されています。Spring で公開された MBean のメタデータ駆動型管理インターフェースを利用するために必要なことはこれだけです。

ソースレベルのメタデータ型

次の表は、Spring JMX で使用できるソースレベルのメタデータ型を示しています。

表 1: ソースレベルのメタデータ型
目的 アノテーション アノテーション型

Class のすべてのインスタンスを JMX 管理対象リソースとしてマークします。

@ManagedResource

クラス

メソッドを JMX 操作としてマークします。

@ManagedOperation

メソッド

getter または setter を JMX 属性の半分としてマークします。

@ManagedAttribute

メソッド (getter および setter のみ)

操作パラメーターの説明を定義します。

@ManagedOperationParameter and @ManagedOperationParameters

メソッド

次の表に、これらのソースレベルのメタデータ型で使用できる構成パラメーターを示します。

表 2: ソースレベルのメタデータパラメーター
パラメーター 説明 適用先

ObjectName

マネージリソースの ObjectName を決定するために MetadataNamingStrategy によって使用されます。

ManagedResource

description

リソース、属性、操作のわかりやすい説明を設定します。

ManagedResource, ManagedAttribute, ManagedOperation, or ManagedOperationParameter

currencyTimeLimit

currencyTimeLimit 記述子フィールドの値を設定します。

ManagedResource or ManagedAttribute

defaultValue

defaultValue 記述子フィールドの値を設定します。

ManagedAttribute

log

log 記述子フィールドの値を設定します。

ManagedResource

logFile

logFile 記述子フィールドの値を設定します。

ManagedResource

persistPolicy

persistPolicy 記述子フィールドの値を設定します。

ManagedResource

persistPeriod

persistPeriod 記述子フィールドの値を設定します。

ManagedResource

persistLocation

persistLocation 記述子フィールドの値を設定します。

ManagedResource

persistName

persistName 記述子フィールドの値を設定します。

ManagedResource

name

操作パラメーターの表示名を設定します。

ManagedOperationParameter

index

操作パラメーターのインデックスを設定します。

ManagedOperationParameter

AutodetectCapableMBeanInfoAssembler インターフェースの使用

構成をさらに簡素化するために、Spring には AutodetectCapableMBeanInfoAssembler インターフェースが含まれています。これは、MBeanInfoAssembler インターフェースを継承して、MBean リソースの自動検出のサポートを追加します。AutodetectCapableMBeanInfoAssembler のインスタンスを使用して MBeanExporter を構成する場合、JMX に公開するために Bean を含めることに「投票」することができます。

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="testBean" class="org.springframework.jmx.JmxTestBean">
		<property name="name" value="TEST"/>
		<property name="age" value="100"/>
	</bean>

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

</beans>

上記の構成では、MBeanExporter に Bean が渡されないことに注意してください。ただし、JmxTestBean は ManagedResource 属性でマークされており、MetadataMBeanInfoAssembler がこれを検出し、それを含めるために投票するため、依然として登録されています。このアプローチの唯一の課題は、JmxTestBean の名前にビジネス上の意味があることです。Bean の ObjectName インスタンスの制御で定義されている ObjectName 作成のデフォルト動作を変更することにより、この課題に対処できます。

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 ごとに異なるインターフェースを使用することをお勧めします。この場合、InterfaceBasedMBeanInfoAssembler に interfaceMappings プロパティを介して Properties インスタンスを渡すことができます。各エントリのキーは Bean 名で、各エントリの値はその Bean に使用するインターフェース名のコンマ区切りリストです。

managedInterfaces または interfaceMappings プロパティのいずれかで管理インターフェースが指定されていない場合、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>

前の例では、add メソッドと myOperation メソッドが JMX 操作として公開され、getName()setName(String)getAge() が JMX 属性の適切な半分として公開されていることがわかります。上記のコードでは、メソッドマッピングは JMX に公開されている Bean に適用されます。Bean ごとにメソッドの公開を制御するには、MethodNameMBeanInfoAssembler の methodMappings プロパティを使用して、Bean 名をメソッド名のリストにマップできます。