2011-11-15 29 views
3

我試圖用jmx-exported方法運行一個簡單的應用程序。我不喜歡它(彈簧上下文和CGLIB的「@Configuration」在classpath中):Spring MBeanExporter - 爲MBean命名

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

回答

13

您可以使用Spring上下文提供的說明註解@ *管理:

要做到這一點,你不能以「MBean的」或「MXBean的」後綴,既不SelfNaming實現該接口。 然後,當MBeanExporter將registerBeanInstance(..)並且將使用所有spring註釋(包括屬性,操作,參數等的描述)將該bean轉換爲ModelMBean時,該bean將被檢測爲標準spring「managed bean」。

這樣的要求,你應該在你的Spring上下文聲明的MBeanExporterAnnotationJmxAttributeSource類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接口,這將繞過春命名管理!

+0

非常感謝。修改這個答案非常簡單,沒有XML - 如果有人需要它,請注意註釋。 –

+0

我真的很感激有沒有XML!我卡住了.... – user16655

3

您可以使用KeyNamingStrategy定義XML配置中的所有JMX有關的屬性,不添加任何編譯時依賴於春天到您的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"/> 
+0

這很好,謝謝 – aliopi

相關問題