控制ObjectName实例的Bean

在幕后,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>

上述示例配置了一个KeyNamingStrategy实例,其中包含一个Properties实例,该实例是从映射属性定义的Properties实例和映射属性定义的路径中的属性文件合并而来。在此配置中,testBean bean被赋予ObjectNamebean:name=testBean1,因为这是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名称]。例如,对于以下bean生成的ObjectName将是com.example:type=MyClass,name=myBean

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

配置基于注解的MBean导出

如果您更喜欢使用基于注解的方法来定义您的管理接口,可以使用一个方便的MBeanExporter的子类:AnnotationMBeanExporter。在定义此子类的实例时,您不再需要namingStrategyassemblerattributeSource配置,因为它始终使用标准的基于Java注解的元数据(自动检测也始终启用)。实际上,与定义MBeanExporter bean不同,@EnableMBeanExport @Configuration注解支持更简单的语法,如下例所示:

@Configuration
@EnableMBeanExport
public class AppConfig {

}

如果您更喜欢基于XML的配置,<context:mbean-export/>元素具有相同的目的,并在以下清单中显示:

<context:mbean-export/>

如果需要,您可以提供对特定MBean server的引用,defaultDomain属性(AnnotationMBeanExporter的属性)接受生成的MBean ObjectName域的替代值。这将代替前一节关于MetadataNamingStrategy的完全限定包名的描述,如下例所示:

@EnableMBeanExport(server="myMBeanServer", defaultDomain="myDomain")
@Configuration
ContextConfiguration {

}

以下示例显示了前面基于注解的示例的XML等效项:

<context:mbean-export server="myMBeanServer" default-domain="myDomain"/>
不要在bean类中的JMX注解的自动检测中与基于接口的AOP代理结合使用。基于接口的代理“隐藏”目标类,这也隐藏了JMX管理的资源注解。因此,在这种情况下,您应该使用目标类代理(通过在<aop:config/><tx:annotation-driven/>等上设置'proxy-target-class'标志)。否则,您的JMX bean可能会在启动时被静默忽略。