控制 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
实例而不是使用 bean 键来读取 ObjectName
实例。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
实例,该实例由 mapping 属性定义的 Properties
实例和 mappings 属性定义的路径中的属性文件合并而成。在此配置中,testBean
bean 被赋予 bean:name=testBean1
的 ObjectName
,因为这是 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
。定义此子类的实例时,您不再需要 namingStrategy
、assembler
和 attributeSource
配置,因为它始终使用标准的基于 Java 注解的元数据(也始终启用自动检测)。事实上,除了定义 MBeanExporter
bean 之外,@EnableMBeanExport
@Configuration
注解或 <context:mbean-export/>
元素还支持更简单的语法,如以下示例所示:
如有必要,您可以提供对特定 MBean server
的引用,并且 defaultDomain
属性(AnnotationMBeanExporter
的一个属性)接受生成的 MBean ObjectName
域的备用值。这取代了上一节 MetadataNamingStrategy 中描述的完全限定包名,如以下示例所示:
请勿将基于接口的 AOP 代理与 bean 类中 JMX 注解的自动检测结合使用。基于接口的代理会“隐藏”目标类,这也会隐藏 JMX 管理的资源注解。因此,在这种情况下,您应该使用目标类代理(通过在 <aop:config/>
、<tx:annotation-driven/>
等上设置“proxy-target-class”标志)。否则,您的 JMX bean 可能会在启动时被静默忽略。