此版本仍在开发中,尚未被视为稳定版本。最新的稳定版本请使用 Spring Framework 6.1.13spring-doc.cn

此版本仍在开发中,尚未被视为稳定版本。最新的稳定版本请使用 Spring Framework 6.1.13spring-doc.cn

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

为通知注册侦听器

Spring 的 JMX 支持使得向任意数量的 MBean 注册任意数量的 变得容易(这包括由 Spring 的 MBean 通过其他机制注册)。为 例如,考虑这样一个场景:每次目标 MBean 的属性发生更改时,都希望收到通知(通过 )。以下内容 示例将通知写入控制台:NotificationListenersMBeanExporterNotificationspring-doc.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());
	}

}

下面的示例添加(在前面的 example) 设置为 :ConsoleLoggingNotificationListenernotificationListenerMappingsspring-doc.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>

有了前面的配置,每次从 目标 MBean () 中,bean 通过属性注册为侦听器的 通知。然后,Bean 可以执行任何操作 它认为回应 .Notificationbean:name=testBean1ConsoleLoggingNotificationListenernotificationListenerMappingsConsoleLoggingNotificationListenerNotificationspring-doc.cn

你也可以使用直接的 bean 名称作为导出的 bean 和侦听器之间的链接。 如下例所示:spring-doc.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>

如果要为所有 bean 注册单个实例 ,你可以使用特殊的通配符 () 作为属性中某个项的键 map,如下例所示:NotificationListenerMBeanExporter*notificationListenerMappingsspring-doc.cn

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

如果需要执行相反的操作(即,针对 一个 MBean),则必须改用 list 属性(在 preference 添加到属性中)。这一次,不是 配置 a 对于单个 MBean,我们配置实例。A 封装了 a 和它要成为的 (或 ) 在 中注册。还封装了 许多其他属性,例如 a 和任意 handback 对象。notificationListenersnotificationListenerMappingsNotificationListenerNotificationListenerBeanNotificationListenerBeanNotificationListenerObjectNameObjectNamesMBeanServerNotificationListenerBeanNotificationFilterspring-doc.cn

使用实例时的配置不是 与前面介绍的内容不同,如下例所示:NotificationListenerBeanspring-doc.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>

前面的示例等效于第一个通知示例。那么,假设 我们希望每次引发 a 时都得到一个 handback 对象,并且 我们还希望通过提供 .以下示例可实现这些目标:NotificationNotificationsNotificationFilterspring-doc.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>

(有关什么是 handback 对象的完整讨论,以及 确实,什么是 A 是什么,请参阅 JMX 的部分 规范 (1.2) 标题为“JMX 通知模型”。NotificationFilterspring-doc.cn

发布通知

Spring 不仅支持注册接收,还支持 用于发布 .NotificationsNotificationsspring-doc.cn

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

Spring 的 JMX 通知发布支持中的关键接口是接口(在包中定义)。任何将要 通过实例导出为 MBean 可以实现相关接口来获取对实例的访问权。该接口通过一个简单的 setter 方法向实现 bean 提供 a 的实例, 然后 Bean 可以使用它来发布 。NotificationPublisherorg.springframework.jmx.export.notificationMBeanExporterNotificationPublisherAwareNotificationPublisherNotificationPublisherAwareNotificationPublisherNotificationsspring-doc.cn

NotificationPublisher 接口的 javadoc 中所述,通过该机制发布事件的受管 bean 不负责通知侦听器的状态管理。 Spring 的 JMX 支持负责处理所有 JMX 基础结构问题。 作为应用程序开发人员,您需要做的就是实现接口并开始使用 提供的实例。请注意,这是在托管 Bean 注册到 .NotificationPublisherNotificationPublisherAwareNotificationPublisherNotificationPublisherMBeanServerspring-doc.cn

使用实例非常简单。您创建一个 JMX 实例(或适当子类的实例), 使用与要发生的事件相关的数据填充通知 published,并在实例上调用 ,传入 .NotificationPublisherNotificationNotificationsendNotification(Notification)NotificationPublisherNotificationspring-doc.cn

在以下示例中,每次调用该操作时,都会导出 publish a 的实例:JmxTestBeanNotificationEventadd(int, int)spring-doc.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;
	}

}

界面和使其正常工作的机制是其中之一 Spring 的 JMX 支持的更好功能。然而,它的价格标签确实是 将你的类耦合到 Spring 和 JMX。一如既往,这里的建议是 务实。如果您需要 和 你可以接受到 Spring 和 JMX 的耦合,然后这样做。NotificationPublisherNotificationPublisherspring-doc.cn

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