控制 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 被赋予了 ObjectName
为 bean: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-name]。例如,为以下 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"/>
不要将基于接口的 AOP 代理与在您的 bean 类中自动检测 JMX 注解结合使用。基于接口的代理会“隐藏”目标类,这也隐藏了 JMX 管理的资源注解。因此,在这种情况下,您应该使用目标类代理(通过在 <aop:config/> 、<tx:annotation-driven/> 等上设置 'proxy-target-class' 标志)。否则,您的 JMX bean 可能会在启动时被静默忽略。
|