控制 Bean 的ObjectName 实例

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

从属性读取ObjectName 实例

您可以配置您自己的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 实例配置KeyNamingStrategy 实例,该实例由映射属性定义的Properties 实例和映射属性定义的路径中的属性文件合并而成。在此配置中,testBean Bean 被赋予bean:name=testBean1ObjectName,因为这是Properties 实例中具有与 Bean 键对应的键的条目。

如果找不到Properties 实例中的条目,则使用 Bean 键名称作为ObjectName

使用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[完全限定的包名]:type=[简短类名],name=[bean-name]。例如,以下 Bean 的生成的ObjectName 将为com.example:type=MyClass,name=myBean

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

配置基于注解的 MBean 导出

如果您更喜欢使用基于注解的方法来定义您的管理接口,则可以使用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 注解的自动检测结合使用。基于接口的代理“隐藏”了目标类,这也隐藏了 JMX 管理的资源注解。因此,在这种情况下,您应该使用目标类代理(通过在<aop:config/><tx:annotation-driven/> 等上设置“proxy-target-class”标志)。否则,您的 JMX Bean 可能会在启动时被静默忽略。