Spring MBeanExporter - 为MBean命名

时间:2011-11-15 14:35:09

标签: spring jmx

我正在尝试使用jmx-exported方法运行一个简单的应用程序。我喜欢(spring-context和“@Configuration”的cglib在classpath中):

package com.sopovs.moradanen.jmx;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jmx.export.MBeanExporter;
import org.springframework.stereotype.Component;

@Component
@Configuration
public class SpringJmxTest {
public static void main(String[] args) {
    new AnnotationConfigApplicationContext("com.sopovs.moradanen.jmx");
    while (true) {
        Thread.yield();
    }
}

@Bean
public MBeanExporter createJmxExporter() {
    return new MBeanExporter();
}

public interface FooBarMBean {
    public String hello();
}

@Component
public static class FooBar implements FooBarMBean {
    @Override
    public String hello() {
        return "Hello";
    }
}
}

但是当我运行它时,我得到:javax.management.MalformedObjectNameException:键属性不能为空。我尝试调试并用以下方法解决它:

@Component
public static class FooBar implements FooBarMBean, SelfNaming {
    @Override
    public String hello() {
        return "Hello";
    }

    @Override
    public ObjectName getObjectName() throws MalformedObjectNameException {
        return new ObjectName("fooBar:name=" + getClass().getName());
    }
}

但是有更好的方法为MBean提供名称吗?

3 个答案:

答案 0 :(得分:14)

您可以使用Spring Context @ Managed *提供的描述注释:

为此,您不能使用“MBean”或“MXBean”后缀实现接口,也不能实现SelfNaming。 然后,当MBeanExporter将registerBeanInstance(..)时,bean将被检测为标准spring“托管bean”,并将使用所有spring注释转换为ModelMBean,包括属性,操作,参数等的描述。

作为一项要求,您应该在春季上下文中声明 MBeanExporter AnnotationJmxAttributeSource MetadataNamingStrategy MetadataMBeanInfoAssembler 属性,可以这样简化:

<bean id="mbeanExporter"
     class="org.springframework.jmx.export.annotation.AnnotationMBeanExporter" />

<context:mbean-export />

您的托管bean应如下所示:

@Component("myManagedBean")
@ManagedResource(objectName="your.domain.jmx:name=MyMBean",
                 description="My MBean goal")
public class AnnotationTestBean {

    private int age;

    @ManagedAttribute(description="The age attribute", currencyTimeLimit=15)
    public int getAge() {
        return age;
    }

    @ManagedOperation(description = "Check permissions for the given activity")
    @ManagedOperationParameters( {
        @ManagedOperationParameter(name = "activity",
                                   description = "The activity to check")
    })
    public boolean isAllowedTo(final String activity) {
        // impl
    }
}

请记住,不要实现MBean接口(可能是StandardMBean)和SelfNaming接口,它会绕过Spring命名管理!

答案 1 :(得分:3)

您可以使用KeyNamingStrategy在XML配置中定义所有与JMX相关的属性,而无需向Spring添加任何编译时依赖性到您的MBean的源代码中:

<bean class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
    <property name="namingStrategy" ref="namingStrategy"/>
</bean>
<bean id="namingStrategy"
        class="org.springframework.jmx.export.naming.KeyNamingStrategy">
    <property name="mappings">
        <props>
            <prop key="someSpringBean">desired.packageName:name=desiredBeanName</prop>
        </props>
    </property>
</bean>

如果您可以使用某些任意对象名称,那么您可以使用IdentityNamingStrategy作为MBeanExporter的命名策略,并进一步最小化XML配置事件:

<bean class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
    <property name="namingStrategy" ref="namingStrategy"/>
</bean>
<bean id="namingStrategy"
        class="org.springframework.jmx.export.naming.IdentityNamingStrategy"/>

答案 2 :(得分:1)

检查spring文档:http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/jmx.html第22.3.2节解释了可用的JDK 5.0注释。

第22.4节解释了可用于对象命名的机制。