Controlling ObjectName Instances for Your Beans

在后台,“MBeanExporter”委托给 ObjectNamingStrategy 的实现来为它注册的每个 bean 获取 ObjectName 实例。默认情况下,默认实现 KeyNamingStrategy 使用 beans Map 的键作为 ObjectName。此外,KeyNamingStrategy 可以将 beans Map 的键映射到 Properties 文件(或文件)中的一个项来解析 ObjectName。除了 KeyNamingStrategy 之外,Spring 还提供了两个附加 ObjectNamingStrategy 实现:IdentityNamingStrategy(基于 bean 的 JVM 标识构建 ObjectName)和 MetadataNamingStrategy(使用源代码级别元数据获取 ObjectName)。

Reading ObjectName Instances from Properties

你可以配置你自己的 KeyNamingStrategy 实例,并将其配置为从 Properties 实例读取 ObjectName 实例,而不是使用 bean 键。KeyNamingStrategy 尝试在 Properties 中查找一个键与 bean 键相对应的项。如果没有找到该项,或者 Properties 实例为 null,则会使用 bean 键本身。

以下代码显示了 KeyNamingStrategy 的示例配置:

<beans>

	<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
		<property name="beans">
			<map>
				<entry key="testBean" value-ref="testBean"/>
			</map>
		</property>
		<property name="namingStrategy" ref="namingStrategy"/>
	</bean>

	<bean id="testBean" class="org.springframework.jmx.JmxTestBean">
		<property name="name" value="TEST"/>
		<property name="age" value="100"/>
	</bean>

	<bean id="namingStrategy" class="org.springframework.jmx.export.naming.KeyNamingStrategy">
		<property name="mappings">
			<props>
				<prop key="testBean">bean:name=testBean1</prop>
			</props>
		</property>
		<property name="mappingLocations">
			<value>names1.properties,names2.properties</value>
		</property>
	</bean>

</beans>

前面的示例使用由映射属性定义的 Properties 实例和映射属性定义的路径中找到的属性文件合并的 Properties 实例来配置 KeyNamingStrategy 的一个实例。在此配置中,testBean bean 被赋予 ObjectName bean:name=testBean1,因为这是 Properties 实例中键与 bean 键相对应的项。

如果在 Properties 实例中找不到任何项,则 bean 键名称将用作 ObjectName

Using MetadataNamingStrategy

MetadataNamingStrategy 使用每个 bean 上 ManagedResource 属性的 objectName 属性来创建 ObjectName。以下代码显示了 MetadataNamingStrategy 的配置:

<beans>

	<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
		<property name="beans">
			<map>
				<entry key="testBean" value-ref="testBean"/>
			</map>
		</property>
		<property name="namingStrategy" ref="namingStrategy"/>
	</bean>

	<bean id="testBean" class="org.springframework.jmx.JmxTestBean">
		<property name="name" value="TEST"/>
		<property name="age" value="100"/>
	</bean>

	<bean id="namingStrategy" class="org.springframework.jmx.export.naming.MetadataNamingStrategy">
		<property name="attributeSource" ref="attributeSource"/>
	</bean>

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

</beans>

如果尚未针对 ManagedResource 属性提供 objectName,则使用以下格式创建一个 ObjectName[fully-qualified-package-name]:type=[short-classname],name=[bean-name]。例如,以下 bean 生成的 ObjectName 将是 com.example:type=MyClass,name=myBean

<bean id="myBean" class="com.example.MyClass"/>

Configuring Annotation-based MBean Export

如果您愿意使用 the annotation-based approach 定义管理接口,可以使用 MBeanExporter 的一个便捷子类:AnnotationMBeanExporter。定义此子类的实例时,不再需要 namingStrategyassemblerattributeSource 配置,因为它始终使用标准的基于 Java 注解的元数据(自动检测始终启用)。实际上,与定义 MBeanExporter bean 相比,@EnableMBeanExport @Configuration 注解或 <context:mbean-export/> 元素支持更简单的语法,如下例所示:

  • Java

  • Kotlin

  • Xml

@Configuration
@EnableMBeanExport
public class JmxConfiguration {
}
@Configuration
@EnableMBeanExport
class JmxConfiguration
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:context="http://www.springframework.org/schema/context"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans
	   https://www.springframework.org/schema/beans/spring-beans.xsd
	   http://www.springframework.org/schema/context
	   https://www.springframework.org/schema/context/spring-context.xsd">

	<context:mbean-export/>
</beans>

如有必要,您可以提供对特定 MBean server 的引用,并且 defaultDomain 属性(AnnotationMBeanExporter 的属性)接受生成 MBean ObjectName 域的备用值。这将用于代替前面 MetadataNamingStrategy 部分中描述的完全限定包名称,如下图所示:

  • Java

  • Kotlin

  • Xml

@Configuration
@EnableMBeanExport(server="myMBeanServer", defaultDomain="myDomain")
public class CustomJmxConfiguration {
}
@Configuration
@EnableMBeanExport(server="myMBeanServer", defaultDomain="myDomain")
class CustomJmxConfiguration
<beans xmlns="http://www.springframework.org/schema/beans"
	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:context="http://www.springframework.org/schema/context"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans
	   https://www.springframework.org/schema/beans/spring-beans.xsd
	   http://www.springframework.org/schema/context
	   https://www.springframework.org/schema/context/spring-context.xsd">

	<context:mbean-export server="myMBeanServer" default-domain="myDomain"/>
</beans>

不要将基于接口的 AOP 代理与在 Bean 类中自动检测 JMX 注释相结合使用。基于接口的代理 “hide” 为目标类提供代理,which 也隐藏了 JMX 管理的资源注释。因此,您应在这种情况下使用目标类代理(通过在 <aop:config/><tx:annotation-driven/> 等处设置“proxy-target-class”标志)。否则,您的 JMX Bean 可能会在启动时被忽略。