27.4 控制bean的ObjectNames务

优质
小牛编辑
130浏览
2023-12-01

27.4控制bean的ObjectNames

在底层,MBeanExporter委托了一个ObjectNamingStrategy的实现来获取每个bean在注册时的ObjectName。默认实现为KeyNamingStrategy,ObjectName作为为bean Map的key。而且,KeyNamingStrategy可以将bean Map的key映射到一个属性文件来解析ObjectName。除此KeyNamingStrategy之外,Spring还提供了两个额外的ObjectNamingStrategy实现:一个基于bean的JVM标识来构建ObjectName的IdentityNamingStrategy和使用代码级元数据来获取ObjectName的MetadataNamingStrategy。

27.4.4 从属性中读取ObjectName

你可以配置自己的KeyNamingStrategy实例,并从一个配置的属性实例中读取ObjectName,而不是bean 的key。KeyNamingStrategy将尝试使用bean对应的key来找出它在Properties中的入口。如果没有找到入口或Properties实例为空,那么bean将使用它自己的key。 下面的代码展示了KeyNamingStrategy的一个简单配置:

<beans>

    <bean 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 class="org.springframework.jmx.JmxTestBean">
        <property name="name" value="TEST"/>
        <property name="age" value="100"/>
    </bean>

    <bean 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是由mapping属性定义的Properties实例和位于mapping属性定义的目录下的属性文件合并而成。在这个配置中,testBean的ObjectName由bean:name=testBean1定义,因此它是bean的key对应的属性实例的入口。 如果Properties实例中找不到入口,那么bean的key将是它的ObjectName。

27.4.2 使用MetadataNamingStrategy

MetadataNamingStrategy使用每个bean上ManagedResource属性的objectName属性来创建ObjectName。下面代码展示了MetadataNamingStrategy的配置:

<beans>

    <bean 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 class="org.springframework.jmx.JmxTestBean">
        <property name="name" value="TEST"/>
        <property name="age" value="100"/>
    </bean>

    <bean class="org.springframework.jmx.export.naming.MetadataNamingStrategy">
        <property name="attributeSource" ref="attributeSource"/>
    </bean>

    <bean
                        class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/>

</beans>

如果ManagedResource属性没有提供objectName,那么将会用下面的格式创建ObjectName:[fully-qualified-package-name]:type=[short-classname],name=[bean-name]。例如,下面的bean产生的ObjectName为:com.foo:type=MyClass,name=myBean。

<bean class="com.foo.MyClass"/>

27.4.3基于MBean导出的注解配置

如果你更喜欢使用基于注解的方式来定义management接口,则可以很方便的使用MBeanExporter的一个子类:AnnotationMBeanExporter。当定义一个子类的实例时,将不需要再配置namingStrategy,assembler和attributeSource,因为它会使用标注的基于Java 元数据的注解(自动检测一直开启)。实际上,不是定义一个MBeanExporter,@EnableMBeanExport和@Configuration注解支持更简单的语法。

@Configuration@EnableMBeanExport
public class AppConfig {

}

如果你更喜欢XML的配置方式,'context:mbean-export'可以达到相同的目的。

<context:mbean-export/>

如果需要,你可以对特定的MBean 服务提供一个引用,并且defaultDomain(AnnotationMBeanExporter的属性)属性接受生成“ObjectNames”的备用值。如上节的MetadataNamingStrategy所述,它将用于代替完全限定的包名称。

@EnableMBeanExport(server="myMBeanServer", defaultDomain="myDomain")
@Configuration
ContextConfiguration {

}
<context:mbean-export server="myMBeanServer" default-domain="myDomain"/>

不要使用基于接口的AOP代理和JMX注解自动发现相结合的方式。基于接口的代理对隐藏目标类,它也会隐藏JMX管理的resource注解。因此,在这种情况下使用目标类代理:通过在aop:config, tx:annotation-driven等上设置'proxy-target-class'标志,否则,JMX也可能在启动时被忽略。

27.5 JSR-160连接器

对于远程访问,Spring JMX模块在org.springframework.jmx.support package包中提供了两种FactoryBean实现,用于创建服务端和客户端的连接器。