Spring MBeanExporter-为MBean命名 [英] Spring MBeanExporter - giving name to MBean

查看:146
本文介绍了Spring MBeanExporter-为MBean命名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用jmx-exported方法运行一个简单的应用程序.我这样做("@Configuration"的spring-context和cglib在类路径中):

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提供名称吗?

解决方案

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

为此,您不得使用"MBean"或"MXBean"后缀(两者都不是SelfNaming)来实现该接口. 然后,当MBeanExporter将注册BeanInstance(..)时,该Bean将被检测为标准的春季托管Bean",并使用所有春季注释(包括属性,操作,参数等的描述)将其转换为ModelMBean.

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

<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命名管理!

I'm trying to run a simple application with jmx-exported method. I do it like (spring-context and cglib for "@Configuration" are in 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";
    }
}
}

However when I run it I get:javax.management.MalformedObjectNameException: Key properties cannot be empty. I tried to debug and solved it with:

@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());
    }
}

But is there a better way to supply a name for MBean?

解决方案

You can use the descriptions annotations provided by Spring Context @Managed* :

To do this, you must NOT implements the interface with "MBean" or "MXBean" suffix, neither SelfNaming. Then, the bean will be detected as a standard spring "managed bean" when MBeanExporter will registerBeanInstance(..), and will be converted to a ModelMBean using all spring annotations, including descriptions of attributes, operations, parameters, etc..

As a requirement, you should declare in your spring context the MBeanExporter with AnnotationJmxAttributeSource, MetadataNamingStrategy, and MetadataMBeanInfoAssembler attributes, which can be simplified like this :

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

or

<context:mbean-export />

And your managed bean should look like this :

@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
    }
}

Remember to not implements an MBean interface, which would be a StandardMBean, and SelfNaming interface, which would bypass Spring naming management !

这篇关于Spring MBeanExporter-为MBean命名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆