通知
Spring の JMX 製品には、JMX 通知の包括的なサポートが含まれています。
通知用のリスナーの登録
Spring の JMX サポートにより、任意の数の NotificationListeners
を任意の数の MBean に簡単に登録できます(これには、Spring の MBeanExporter
によってエクスポートされた MBean および他のメカニズムを通じて登録された MBean が含まれます)。例: ターゲット MBean の属性が変更されるたびに(Notification
を介して)情報を受け取りたいシナリオを考えます。次の例では、コンソールに通知を書き込みます。
package com.example;
import javax.management.AttributeChangeNotification;
import javax.management.Notification;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
public class ConsoleLoggingNotificationListener
implements NotificationListener, NotificationFilter {
public void handleNotification(Notification notification, Object handback) {
System.out.println(notification);
System.out.println(handback);
}
public boolean isNotificationEnabled(Notification notification) {
return AttributeChangeNotification.class.isAssignableFrom(notification.getClass());
}
}
次の例では、ConsoleLoggingNotificationListener
(前の例で定義)を notificationListenerMappings
に追加します。
<beans>
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="beans">
<map>
<entry key="bean:name=testBean1" value-ref="testBean"/>
</map>
</property>
<property name="notificationListenerMappings">
<map>
<entry key="bean:name=testBean1">
<bean class="com.example.ConsoleLoggingNotificationListener"/>
</entry>
</map>
</property>
</bean>
<bean id="testBean" class="org.springframework.jmx.JmxTestBean">
<property name="name" value="TEST"/>
<property name="age" value="100"/>
</bean>
</beans>
上記の構成を使用すると、ターゲット MBean(bean:name=testBean1
)から JMX Notification
がブロードキャストされるたびに、notificationListenerMappings
プロパティを介してリスナーとして登録された ConsoleLoggingNotificationListener
Bean に通知されます。ConsoleLoggingNotificationListener
Bean は、Notification
に応じて適切と判断したアクションを実行できます。
次の例に示すように、エクスポートされた Bean とリスナー間のリンクとして、ストレート Bean 名を使用することもできます。
<beans>
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="beans">
<map>
<entry key="bean:name=testBean1" value-ref="testBean"/>
</map>
</property>
<property name="notificationListenerMappings">
<map>
<entry key="testBean">
<bean class="com.example.ConsoleLoggingNotificationListener"/>
</entry>
</map>
</property>
</bean>
<bean id="testBean" class="org.springframework.jmx.JmxTestBean">
<property name="name" value="TEST"/>
<property name="age" value="100"/>
</bean>
</beans>
取り囲む MBeanExporter
がエクスポートするすべての Bean に対して単一の NotificationListener
インスタンスを登録する場合、次の例に示すように、notificationListenerMappings
プロパティマップのエントリのキーとして特別なワイルドカード(*
)を使用できます。
<property name="notificationListenerMappings">
<map>
<entry key="*">
<bean class="com.example.ConsoleLoggingNotificationListener"/>
</entry>
</map>
</property>
逆を行う(つまり、MBean に対して多数の個別のリスナーを登録する)必要がある場合は、代わりに(notificationListenerMappings
プロパティよりも) notificationListeners
リストプロパティを使用する必要があります。今回は、単一の MBean に対して NotificationListener
を構成する代わりに、NotificationListenerBean
インスタンスを構成します。NotificationListenerBean
は、NotificationListener
と ObjectName
(または ObjectNames
)をカプセル化し、それが MBeanServer
で登録されます。NotificationListenerBean
は、NotificationFilter
や高度な JMX 通知シナリオで使用できる任意のハンドバックオブジェクトなど、他の多くのプロパティもカプセル化します。
NotificationListenerBean
インスタンスを使用する場合の構成は、次の例に示すように、以前に提示されたものと大きく変わりません。
<beans>
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="beans">
<map>
<entry key="bean:name=testBean1" value-ref="testBean"/>
</map>
</property>
<property name="notificationListeners">
<list>
<bean class="org.springframework.jmx.export.NotificationListenerBean">
<constructor-arg>
<bean class="com.example.ConsoleLoggingNotificationListener"/>
</constructor-arg>
<property name="mappedObjectNames">
<list>
<value>bean:name=testBean1</value>
</list>
</property>
</bean>
</list>
</property>
</bean>
<bean id="testBean" class="org.springframework.jmx.JmxTestBean">
<property name="name" value="TEST"/>
<property name="age" value="100"/>
</bean>
</beans>
上記の例は、最初の通知の例と同等です。それでは、Notification
が発生するたびにハンドバックオブジェクトを与えたいと考え、また NotificationFilter
を供給することで余分な Notifications
を除外したいとします。次の例は、これらのゴールを達成します。
<beans>
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="beans">
<map>
<entry key="bean:name=testBean1" value-ref="testBean1"/>
<entry key="bean:name=testBean2" value-ref="testBean2"/>
</map>
</property>
<property name="notificationListeners">
<list>
<bean class="org.springframework.jmx.export.NotificationListenerBean">
<constructor-arg ref="customerNotificationListener"/>
<property name="mappedObjectNames">
<list>
<!-- handles notifications from two distinct MBeans -->
<value>bean:name=testBean1</value>
<value>bean:name=testBean2</value>
</list>
</property>
<property name="handback">
<bean class="java.lang.String">
<constructor-arg value="This could be anything..."/>
</bean>
</property>
<property name="notificationFilter" ref="customerNotificationListener"/>
</bean>
</list>
</property>
</bean>
<!-- implements both the NotificationListener and NotificationFilter interfaces -->
<bean id="customerNotificationListener" class="com.example.ConsoleLoggingNotificationListener"/>
<bean id="testBean1" class="org.springframework.jmx.JmxTestBean">
<property name="name" value="TEST"/>
<property name="age" value="100"/>
</bean>
<bean id="testBean2" class="org.springframework.jmx.JmxTestBean">
<property name="name" value="ANOTHER TEST"/>
<property name="age" value="200"/>
</bean>
</beans>
(ハンドバックオブジェクトとは何か、実際には NotificationFilter
とは何かについての詳細は、「JMX 通知モデル」というタイトルの JMX 仕様(1.2)のセクションを参照してください)
通知の公開
Spring は、Notifications
を受信するための登録だけでなく、Notifications
の公開もサポートします。
このセクションは、実際には MBeanExporter を介して MBean として公開された Spring 管理 Bean のみに関連しています。既存のユーザー定義 MBean は、通知の公開に標準の JMX API を使用する必要があります。 |
Spring の JMX 通知発行サポートの主要なインターフェースは、NotificationPublisher
インターフェースです(org.springframework.jmx.export.notification
パッケージで定義されています)。MBeanExporter
インスタンスを介して MBean としてエクスポートされる Bean は、関連する NotificationPublisherAware
インターフェースを実装して、NotificationPublisher
インスタンスにアクセスできます。NotificationPublisherAware
インターフェースは、NotificationPublisher
のインスタンスを単純な setter メソッドを介して実装 Bean に提供し、Bean はそれを使用して Notifications
を公開できます。
NotificationPublisher
(Javadoc) インターフェースの javadoc に記載されているように、NotificationPublisher
メカニズムを介してイベントを発行するマネージド Bean は、通知リスナーの状態管理を行いません。Spring の JMX サポートは、すべての JMX インフラストラクチャの課題を処理します。アプリケーション開発者として行う必要があるのは、NotificationPublisherAware
インターフェースを実装し、提供された NotificationPublisher
インスタンスを使用してイベントの発行を開始することだけです。NotificationPublisher
は、管理対象 Bean が MBeanServer
に登録された後に設定されることに注意してください。
NotificationPublisher
インスタンスの使用は非常に簡単です。JMX Notification
インスタンス(または適切な Notification
サブクラスのインスタンス)を作成し、発行するイベントに関連するデータを通知に入力し、Notification
を渡して NotificationPublisher
インスタンスで sendNotification(Notification)
を呼び出します。
次の例では、JmxTestBean
のエクスポートされたインスタンスは、add(int, int)
操作が呼び出されるたびに NotificationEvent
を公開します。
package org.springframework.jmx;
import org.springframework.jmx.export.notification.NotificationPublisherAware;
import org.springframework.jmx.export.notification.NotificationPublisher;
import javax.management.Notification;
public class JmxTestBean implements IJmxTestBean, NotificationPublisherAware {
private String name;
private int age;
private boolean isSuperman;
private NotificationPublisher publisher;
// other getters and setters omitted for clarity
public int add(int x, int y) {
int answer = x + y;
this.publisher.sendNotification(new Notification("add", this, 0));
return answer;
}
public void dontExposeMe() {
throw new RuntimeException();
}
public void setNotificationPublisher(NotificationPublisher notificationPublisher) {
this.publisher = notificationPublisher;
}
}
NotificationPublisher
インターフェースとそれをすべて機能させるための機械は、Spring の JMX サポートの優れた機能の 1 つです。ただし、クラスを Spring と JMX の両方に結合する価格タグが付いています。通常どおり、ここでのアドバイスは実用的です。NotificationPublisher
が提供する機能が必要で、Spring と JMX の両方への結合を受け入れることができる場合は、そうしてください。