对于最新的稳定版本,请使用 Spring Framework 6.2.10spring-doc.cadn.net.cn

通知

Spring 的 JMX 产品包括对 JMX 通知的全面支持。spring-doc.cadn.net.cn

注册通知侦听器

Spring 的 JMX 支持可以轻松注册任意数量的NotificationListeners具有任意数量的 MBean(这包括由Spring 的MBeanExporter以及通过其他机制注册的 MBean)。 为 例如,考虑希望获得通知的场景(通过Notification) 每次目标 MBean 的属性发生变化时。以下示例将通知写入控制台:spring-doc.cadn.net.cn

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:spring-doc.cadn.net.cn

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

有了上述配置,每次 JMXNotification从目标 MBean (bean:name=testBean1)、ConsoleLoggingNotificationListener豆 通过notificationListenerMappings属性是 通知。 这ConsoleLoggingNotificationListener然后,bean 可以采取任何它认为适当的作来响应Notification.spring-doc.cadn.net.cn

您还可以使用直接的 bean 名称作为导出的 bean 和侦听器之间的链接,如以下示例所示:spring-doc.cadn.net.cn

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

如果您想注册单个NotificationListener所有 bean 的实例封闭的MBeanExporterexports,您可以使用特殊通配符 ()作为*notificationListenerMappings财产 map,如以下示例所示:spring-doc.cadn.net.cn

<property name="notificationListenerMappings">
	<map>
		<entry key="*">
			<bean class="com.example.ConsoleLoggingNotificationListener"/>
		</entry>
	</map>
</property>

如果您需要执行相反的作(即,针对MBean 注册多个不同的侦听器),则必须改用notificationListenerslist 属性(在首选项对notificationListenerMappings属性)。这一次,而不是配置一个NotificationListener对于单个 MBean,我们配置NotificationListenerBean实例。 一个NotificationListenerBean封装一个NotificationListenerObjectName(或ObjectNames) 将在MBeanServer.这NotificationListenerBean还封装了许多其他属性,例如NotificationFilter以及一个任意回拨对象,可用于高级 JMX 通知场景。spring-doc.cadn.net.cn

使用时的配置NotificationListenerBean实例并不疯狂与之前介绍的内容不同,如以下示例所示:spring-doc.cadn.net.cn

<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被提高,并且我们还想过滤掉无关的Notifications通过提供NotificationFilter. 以下示例实现了这些目标:spring-doc.cadn.net.cn

<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规范 (1.2) 标题为“JMX 通知模型”的部分。spring-doc.cadn.net.cn

发布通知

Spring 不仅支持注册接收Notifications还用于出版Notifications.spring-doc.cadn.net.cn

本节实际上只与 Spring 管理的 Bean 相关,这些 Bean通过MBeanExporter. 任何现有的用户定义 MBean 都应该使用标准 JMX API 进行通知发布。

Spring 的 JMX 通知发布支持中的关键接口是NotificationPublisher接口(在org.springframework.jmx.export.notificationpackage)中。任何将要通过MBeanExporter实例可以实现相关的NotificationPublisherAware接口以访问NotificationPublisher实例。 这NotificationPublisherAware接口提供NotificationPublisher通过简单的 setter 方法到实现 bean,然后 bean 可以使用它来发布Notifications.spring-doc.cadn.net.cn

如 javadoc 中所述NotificationPublisher接口,托管 Bean 通过NotificationPublisher机制不负责通知监听器的状态管理。Spring 的 JMX 支持负责处理所有 JMX 基础设施问题。作为应用程序开发人员,您需要做的就是实现NotificationPublisherAware接口,然后使用 提供NotificationPublisher实例。 请注意,NotificationPublisher在向MBeanServer.spring-doc.cadn.net.cn

使用NotificationPublisher实例非常简单。您创建了一个 JMXNotification实例(或适当的Notification子类), 使用与要发生的事件相关的数据填充通知 published,并调用sendNotification(Notification)NotificationPublisher实例,传入Notification.spring-doc.cadn.net.cn

在以下示例中,导出的JmxTestBean发布一个NotificationEvent每次add(int, int)作被调用:spring-doc.cadn.net.cn

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 支持的更好功能。然而,它确实带有 将您的类耦合到 Spring 和 JMX。与往常一样,这里的建议是 务实。如果您需要NotificationPublisher和 您可以接受与 Spring 和 JMX 的耦合,然后这样做。spring-doc.cadn.net.cn