Spring MBeanExporter-为MBean命名 [英] Spring MBeanExporter - giving name to 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屋!