如需使用最新稳定版本,请使用 Spring Integration 7.0.4spring-doc.cadn.net.cn

JMX 支持

Spring Integration 提供了通道适配器,用于接收和发布 JMX 通知。spring-doc.cadn.net.cn

您需要将以下依赖项包含到您的项目中:spring-doc.cadn.net.cn

<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-jmx</artifactId>
    <version>6.4.10</version>
</dependency>
compile "org.springframework.integration:spring-integration-jmx:6.4.10"

入站通道适配器允许轮询 JMX MBean 属性值,而出站通道适配器允许调用 JMX MBean 操作。spring-doc.cadn.net.cn

通知监听通道适配器

通知监听通道适配器需要一个 JMX ObjectName,用于发布该监听器应注册的 MBean 的通知。 一个非常简单的配置可能如下所示:spring-doc.cadn.net.cn

<int-jmx:notification-listening-channel-adapter id="adapter"
    channel="channel"
    object-name="example.domain:name=publisher"/>
The notification-listening-channel-adapter registers with an MBeanServer at startup, and the default bean name is mbeanServer, which happens to be the same bean name generated when using Spring's <context:mbean-server/> element. If you need to use a different name, be sure to include the mbean-server attribute.

适配器还可以接受对 NotificationFilter 的引用以及一个“回传”对象,以提供随每次通知一起返回的上下文信息。 这两个属性都是可选的。 在 preceding example(前例)的基础上扩展,包含这些属性以及一个明确的 MBeanServer bean 名称,将产生以下示例:spring-doc.cadn.net.cn

<int-jmx:notification-listening-channel-adapter id="adapter"
    channel="channel"
    mbean-server="someServer"
    object-name="example.domain:name=somePublisher"
    notification-filter="notificationFilter"
    handback="myHandback"/>

The _Notification-listening channel adapter is event-driven and registered with the MBeanServer directly. It does not require any poller configuration.spring-doc.cadn.net.cn

对于此组件,object-name 属性可以包含一个对象名称模式(例如, "org.something:type=MyType,name=*")。 在这种情况下,适配器会接收来自所有与模式匹配的对象名称的 MBeans 的通知。 此外,object-name 属性可以包含对 <util:list> 中对象名称模式的 SpEL 引用,如下例所示:spring-doc.cadn.net.cn

<jmx:notification-listening-channel-adapter id="manyNotificationsAdapter"
    channel="manyNotificationsChannel"
    object-name="#{patterns}"/>

<util:list id="patterns">
    <value>org.foo:type=Foo,name=*</value>
    <value>org.foo:type=Bar,name=*</value>
</util:list>

当启用 DEBUG 级别日志记录时,找到的 MBean 的名称会被记录。spring-doc.cadn.net.cn

通知发布通道适配器

通知发布通道适配器相对简单。 它配置中仅需一个 JMX 对象名称,如下例所示:spring-doc.cadn.net.cn

<context:mbean-export/>

<int-jmx:notification-publishing-channel-adapter id="adapter"
    channel="channel"
    object-name="example.domain:name=publisher"/>

它还要求上下文中存在一个MBeanExporter。 这就是为什么在前面的示例中也显示了<context:mbean-export/>元素。spring-doc.cadn.net.cn

当消息被发送到此适配器的通道时,通知是根据消息内容创建的。 如果有效负载为 String,则将其作为通知的 message 文本传递。 任何其他类型的有效负载都将作为通知的 userData 传递。spring-doc.cadn.net.cn

JMX 通知也具有 type,它应该是一个点分隔的 String。 有两种方法可以提供 type。 始终优先处理与 JmxHeaders.NOTIFICATION_TYPE 键关联的消息头值。 或者,您可以在配置中提供一个回退 default-notification-type 属性,如下例所示:spring-doc.cadn.net.cn

<context:mbean-export/>

<int-jmx:notification-publishing-channel-adapter id="adapter"
    channel="channel"
    object-name="example.domain:name=publisher"
    default-notification-type="some.default.type"/>

属性轮询通道适配器

属性轮询通道适配器在需要定期检查通过 MBean 作为托管属性提供的某个值时非常有用。 您可以像配置 Spring Integration 中的任何其他轮询适配器一样配置轮询器(或者依赖默认轮询器)。 object-nameattribute-name 是必需的。 还需要一个 MBeanServer 引用。 然而,默认情况下,它会自动查找名为 mbeanServer 的 bean,这与前面描述的通知监听通道适配器相同。 以下示例展示了如何使用 XML 配置属性轮询通道适配器:spring-doc.cadn.net.cn

<int-jmx:attribute-polling-channel-adapter id="adapter"
    channel="channel"
    object-name="example.domain:name=someService"
    attribute-name="InvocationCount">
        <int:poller max-messages-per-poll="1" fixed-rate="5000"/>
</int-jmx:attribute-polling-channel-adapter>

树轮询通道适配器

树轮询通道适配器查询 JMX MBean 树,并发送一条消息,其负载为与查询匹配的对象图。 默认情况下,MBean 被映射为基本类型和简单对象,例如 MapList 和数组。 这样做允许简单地转换为(例如)JSON。 还需要一个 MBeanServer 引用。 然而,默认情况下,它会自动检查名为 mbeanServer 的 Bean,这与前面描述的通知监听通道适配器相同。 以下示例展示了如何使用 XML 配置树轮询通道适配器:spring-doc.cadn.net.cn

<int-jmx:tree-polling-channel-adapter id="adapter"
    channel="channel"
    query-name="example.domain:type=*">
        <int:poller max-messages-per-poll="1" fixed-rate="5000"/>
</int-jmx:tree-polling-channel-adapter>

上述示例包含了所选 MBean 的所有属性。 您可以通过提供一个已配置适当过滤器的 MBeanObjectConverter 来过滤属性。 您可以使用 converter 属性将转换器作为 Bean 定义的引用提供,或者使用内部 <bean/> 定义。 Spring Integration 提供了一个 DefaultMBeanObjectConverter,它可以在其构造函数参数中接受一个 MBeanAttributeFilterspring-doc.cadn.net.cn

Spring Integration 提供了两个标准过滤器。 The NamedFieldsMBeanAttributeFilter 允许您指定要包含的属性列表。 The NotNamedFieldsMBeanAttributeFilter 允许您指定要排除的属性列表。 您也可以实现自己的过滤器。spring-doc.cadn.net.cn

操作调用通道适配器

操作调用通道适配器支持通过消息驱动方式调用由 MBean 公开的任何托管操作。 每次调用都需要指定要调用的操作名称以及目标 MBean 的对象名称。 这两者必须分别通过适配器配置或通过 JmxHeaders.OBJECT_NAMEJmxHeaders.OPERATION_NAME 消息头显式提供:spring-doc.cadn.net.cn

<int-jmx:operation-invoking-channel-adapter id="adapter"
    object-name="example.domain:name=TestBean"
    operation-name="ping"/>

此时适配器只需能够发现 mbeanServer 这个 Bean。 如果需要使用不同的 Bean 名称,则提供带有引用的 mbean-server 属性即可。spring-doc.cadn.net.cn

消息的负载被映射到操作的参数(如果有的话)。 具有 String 个键的 Map 类型负载被视为名称/值对,而 List 或数组则作为简单参数列表传递(无显式参数名)。 如果操作需要单个参数值,则该负载可表示该单个值。 此外,如果操作不需要任何参数,则负载将被忽略。spring-doc.cadn.net.cn

如果您希望为某个单一通用操作暴露一个通道,且该操作由无需包含消息头的消息调用,那么最后一种选项效果很好。spring-doc.cadn.net.cn

调用操作的出站网关

与操作调用通道适配器类似,Spring Integration 还提供了操作调用出站网关,当处理需要返回值的非 void 操作时可以使用它。 返回值将作为消息负载发送到网关指定的 reply-channel。 以下示例展示了如何使用 XML 配置操作调用出站网关:spring-doc.cadn.net.cn

<int-jmx:operation-invoking-outbound-gateway request-channel="requestChannel"
   reply-channel="replyChannel"
   object-name="o.s.i.jmx.config:type=TestBean,name=testBeanGateway"
   operation-name="testWithReturn"/>

如果您未提供 reply-channel 属性,回复消息将发送至由 IntegrationMessageHeaderAccessor.REPLY_CHANNEL 标头标识的通道。 该标头通常由消息流的入口点自动创建,例如任何网关组件。 然而,如果消息流是通过手动创建 Spring Integration 消息并直接将其发送到通道而启动的,则必须显式指定消息标头或使用 reply-channel 属性。spring-doc.cadn.net.cn

MBean 导出器

当配置了IntegrationMBeanExporter时,Spring Integration 组件本身可以暴露为 MBean。 要创建IntegrationMBeanExporter的实例,请定义一个 bean 并提供对MBeanServer和域名(可选)的引用。 您可以省略域名,此时默认域名为org.springframework.integration。 以下示例展示了如何声明IntegrationMBeanExporter的实例以及关联的MBeanServer实例:spring-doc.cadn.net.cn

<int-jmx:mbean-export id="integrationMBeanExporter"
            default-domain="my.company.domain" server="mbeanServer"/>

<bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean">
    <property name="locateExistingServerIfPossible" value="true"/>
</bean>

MBean 导出器与 Spring Core 中提供的导出器是正交的。 它注册消息通道和消息处理器,但不会注册自身。 您可以使用标准的 <context:mbean-export/> 标签来暴露该导出器本身(以及 Spring Integration 中的某些其他组件)。 该导出器附带了一些指标——例如,处理器的数量和队列中消息的数量。spring-doc.cadn.net.cn

它还有一个有用的操作,如有序关闭托管操作中所讨论的。spring-doc.cadn.net.cn

Spring Integration 4.0 引入了 @EnableIntegrationMBeanExport 注解,以便在 @Configuration 类级别方便地配置一个默认类型的 integrationMbeanExporter Bean(类型为 IntegrationMBeanExporter),并提供多种实用选项。 以下示例展示了如何配置此 Bean:spring-doc.cadn.net.cn

@Configuration
@EnableIntegration
@EnableIntegrationMBeanExport(server = "mbeanServer", managedComponents = "input")
public class ContextConfiguration {

	@Bean
	public MBeanServerFactoryBean mbeanServer() {
		return new MBeanServerFactoryBean();
	}
}

如果您需要提供更多选项或拥有多个 IntegrationMBeanExporter bean(例如用于不同的 MBean Server 或为避免与标准 Spring MBeanExporter 发生冲突——例如通过 @EnableMBeanExport),您可以将 IntegrationMBeanExporter 配置为通用 bean。spring-doc.cadn.net.cn

MBean 对象名称

应用程序中的所有 MessageChannelMessageHandlerMessageSource 实例均通过 MBean 导出器进行包装,以提供管理和监控功能。 每种组件类型生成的 JMX 对象名称列在下表中:spring-doc.cadn.net.cn

表 1. MBean 对象名称
组件类型 对象名称

消息通道spring-doc.cadn.net.cn

 `o.s.i:type=MessageChannel,name=<channelName>`

消息源spring-doc.cadn.net.cn

 `o.s.i:type=MessageSource,name=<channelName>,bean=<source>`

消息处理器spring-doc.cadn.net.cn

 `o.s.i:type=MessageSource,name=<channelName>,bean=<source>`

源和处理器对象名称中的bean属性取以下表格中的一个值:spring-doc.cadn.net.cn

表2. bean ObjectName 部分
Bean 值 描述

端点spring-doc.cadn.net.cn

包含端点的 Bean 名称(例如 <service-activator>),如果存在的话spring-doc.cadn.net.cn

匿名spring-doc.cadn.net.cn

指示封闭端点没有用户指定的 Bean 名称,因此 JMX 名称为输入通道名称。spring-doc.cadn.net.cn

内部spring-doc.cadn.net.cn

对于知名的 Spring Integration 默认组件spring-doc.cadn.net.cn

处理器/源码spring-doc.cadn.net.cn

以上都不是。 回退到被监控对象(处理器或源)的toString()方法spring-doc.cadn.net.cn

您可以通过在object-name-static-properties属性中提供对Properties对象的引用来将自定义元素附加到对象名称上。spring-doc.cadn.net.cn

此外,自 Spring Integration 3.0 起,您可以通过设置 object-naming-strategy 属性来使用自定义的 ObjectNamingStrategy。 这样做允许您更灵活地控制 MBean 的名称,例如将所有集成相关的 MBean 归类在 'Integration' 类型下。 以下示例展示了一种可能的自定义命名策略实现:spring-doc.cadn.net.cn

public class Namer implements ObjectNamingStrategy {

	private final ObjectNamingStrategy realNamer = new KeyNamingStrategy();
	@Override
	public ObjectName getObjectName(Object managedBean, String beanKey) throws MalformedObjectNameException {
		String actualBeanKey = beanKey.replace("type=", "type=Integration,componentType=");
		return realNamer.getObjectName(managedBean, actualBeanKey);
	}

}

beanKey参数是一个包含标准对象名称的String,该名称以default-domain开头,并包含任何额外的静态属性。 前面的示例将标准的type部分移动到componentType,并将type设置为'Integration',从而允许在一个查询中选择所有Integration MBean:`my.domain:type=Integration,*`。 这样做还会在VisualVM等工具中将这些bean分组到域下的一个树条目下。spring-doc.cadn.net.cn

默认命名策略是一个 MetadataNamingStrategy。 导出器会将 default-domain 传播到该对象,以便在 bean 键解析失败时生成一个备用对象名称。 如果您的自定义命名策略是 MetadataNamingStrategy(或其子类),则导出器不会传播 default-domain。 您必须在您的策略 bean 上配置它。

从版本 5.1 开始,任何包含 Java 标识符(或点号 .)中不允许的字符的 bean 名称(在对象名称中表示为 name 键),都将被引号括起来。spring-doc.cadn.net.cn

JMX 改进

版本 4.2 引入了一些重要的改进,代表了框架中 JMX 支持的重大重构。 这些改进显著提升了 JMX 统计数据的收集性能,并提供了更多的控制能力。 然而,在某些特定的(不常见的)场景下,它对用户代码产生了一些影响。 以下将详细说明这些变更,并在必要时给出警告。spring-doc.cadn.net.cn

@集成管理资源

@ManagedResource 注解类似,@IntegrationManagedResource 将类标记为可导出为 MBean。 然而,仅当应用上下文包含 IntegrationMBeanExporter 时才会被导出。spring-doc.cadn.net.cn

某些 Spring Integration 类(位于org.springframework.integration包中)之前使用@ManagedResource注解,现在同时使用@ManagedResource@IntegrationManagedResource注解。 这是为了向后兼容(见下一项)。 此类 MBean 由任何上下文MBeanServerIntegrationMBeanExporter导出(但不会两者都导出——如果两个导出器都存在,且该 Bean 匹配managed-components模式,则通过集成导出器导出该 Bean)。spring-doc.cadn.net.cn

MBean Exporter Bean 名称模式

此前,managed-components 模式仅表示包含匹配。 如果 bean 名称与任一模式匹配,则该 bean 会被包含。 现在,可以通过在模式前添加 ! 来否定该模式。 例如,!thing*, things 匹配所有不以 thing 开头的 bean 名称,但排除 things。 模式的评估顺序为从左到右。 第一个匹配(无论是正向还是负向)生效,之后不再应用其他模式。spring-doc.cadn.net.cn

将这种语法添加到模式中会导致一个可能(尽管不太可能)的问题。 如果您有一个名为 "!thing" 的 Bean,并且在 MBean 导出器的 managed-components 模式中包含了 !thing,那么它将不再匹配;此时该模式将匹配所有名称不为 thing 的 Bean。 在这种情况下,您可以使用 \ 对模式中的 ! 进行转义。 \!thing 模式将匹配名为 !thing 的 Bean。
IntegrationMBeanExporter 变更

The IntegrationMBeanExporter 不再实现 SmartLifecycle。 这意味着 start()stop() 操作不再可用于注册和注销 MBean。 MBean 现在在上下文初始化期间注册,并在上下文销毁时注销。spring-doc.cadn.net.cn

有序关闭管理操作

MBean 导出器允许通过 JMX 操作以有序的方式关闭应用程序。 它旨在在停止 JVM 之前使用。 以下示例展示了如何使用它:spring-doc.cadn.net.cn

public void stopActiveComponents(long howLong)

其使用和操作在 有序关闭 中描述。spring-doc.cadn.net.cn