控制 Bean 的 ObjectName
实例
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>
前面的示例配置了一个 KeyNamingStrategy
实例,其中包含一个 Properties
实例,该实例是由映射属性定义的 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
,格式如下:[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"/>
配置基于注解的 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 可能会在启动时被静默忽略。