|
对于最新稳定版本,请使用 Spring Framework 7.0.6! |
为您的 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 实例,并将其设置为从 ObjectName 实例中读取 Properties 实例,而不是使用 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 实例是由 mapping 属性所定义的 Properties 实例与 mappings 属性所指定路径下的属性文件合并而成的。在此配置中,testBean bean 被赋予了一个 ObjectName,其值为 bean:name=testBean1,因为这是 Properties 实例中与 bean 键相对应的键所对应的条目。
如果在 Properties 实例中找不到任何条目,则使用 bean 的键名作为 ObjectName。
使用MetadataNamingStrategy
MetadataNamingStrategy 使用每个 Bean 上 objectName 属性的 ManagedResource 属性来创建 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>
如果未为 objectName 属性提供 ManagedResource,则会按照以下格式创建一个 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 注解还支持更简单的语法,如下例所示:
@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 类中同时使用基于接口的 AOP 代理和 JMX 注解的自动检测。基于接口的代理会“隐藏”目标类,从而也会隐藏 JMX 管理资源相关的注解。因此,在这种情况下,您应使用基于目标类的代理(通过在 <aop:config/>、<tx:annotation-driven/> 等标签中设置 'proxy-target-class' 标志)。否则,您的 JMX Bean 可能在启动时被静默忽略。 |