控制 Bean 的 ObjectName
实例
在幕后,MBeanExporter
委托给 ObjectNamingStrategy
的实现来获取其注册的每个 Bean 的 ObjectName
实例。默认情况下,默认实现 KeyNamingStrategy
使用 beans
Map
的键作为 ObjectName
。此外,KeyNamingStrategy
可以将 beans
Map
的键映射到 Properties
文件(或多个文件)中的条目以解析 ObjectName
。除了 KeyNamingStrategy
,Spring 还提供了另外两个 ObjectNamingStrategy
实现:IdentityNamingStrategy
(它根据 Bean 的 JVM 标识构建 ObjectName
)和 MetadataNamingStrategy
(它使用源级元数据来获取 ObjectName
)。
从 Properties 中读取 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
实例合并了由 mapping
属性定义的 Properties
实例以及由 mappings
属性定义的路径中的属性文件。在此配置中,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 名]。例如,以下 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/>
元素还支持更简单的语法,如下例所示
-
Java
-
Kotlin
-
XML
@Configuration
@EnableMBeanExport
public class JmxConfiguration {
}
@Configuration
@EnableMBeanExport
class JmxConfiguration
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:mbean-export/>
</beans>
如有必要,您可以提供对特定 MBean server
的引用,并且 defaultDomain
属性(AnnotationMBeanExporter
的属性)接受生成的 MBean ObjectName
域的替代值。这会替换上一节使用 MetadataNamingStrategy 中描述的完全限定包名,如下例所示
-
Java
-
Kotlin
-
XML
@Configuration
@EnableMBeanExport(server="myMBeanServer", defaultDomain="myDomain")
public class CustomJmxConfiguration {
}
@Configuration
@EnableMBeanExport(server="myMBeanServer", defaultDomain="myDomain")
class CustomJmxConfiguration
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:mbean-export server="myMBeanServer" default-domain="myDomain"/>
</beans>
不要在 Bean 类中将基于接口的 AOP 代理与 JMX 注解的自动检测结合使用。基于接口的代理会“隐藏”目标类,这也会隐藏 JMX 管理的资源注解。因此,在这种情况下(通过在 <aop:config/> 、<tx:annotation-driven/> 等上设置 'proxy-target-class' 标志),您应该使用目标类代理。否则,您的 JMX Bean 可能会在启动时被静默忽略。 |