跳到主要内容

控制 Bean 的 ObjectName 实例

ChatGPT-4o 中英对照 Controlling ObjectName Instances for Your Beans 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)。

从属性中读取 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>
xml

前面的示例配置了一个 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>
xml

如果没有为 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"/>
xml

配置基于注解的 MBean 导出

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

@Configuration
@EnableMBeanExport
public class JmxConfiguration {
}
java

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

@Configuration
@EnableMBeanExport(server="myMBeanServer", defaultDomain="myDomain")
public class CustomJmxConfiguration {
}
java
警告

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