Change @ManagedResource objectName dynamically

后端 未结 2 2050
囚心锁ツ
囚心锁ツ 2021-01-02 10:45

I am creating prototype beans programatically/dynamically. I want those beans after initiation to be in the jmx console. How I can distinguish between them? I am using anota

相关标签:
2条回答
  • 2021-01-02 11:06

    You can use a a JMX naming strategy to do this. At work we use an interface:

    public interface RuntimeJmxNames {
        /** this is the name= part of the object name */
        public String getJmxName();
        /** this sets the folders as 00=FirstFolder,01=Second */
        public String[] getJmxPath();
    }
    

    I've posted the code to implement the RuntimeMetadataNamingStrategy naming strategy.

    And then something like the following Spring beans:

    <bean id="jmxAttributeSource"
     class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource" />
    
    <bean id="jmxAssembler"
        class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
        <property name="attributeSource" ref="jmxAttributeSource" />
    </bean>
    
    <bean id="jmxNamingStrategy" class="com.j256.jmx.RuntimeMetadataNamingStrategy">
        <property name="attributeSource" ref="jmxAttributeSource" />
    </bean>
    
    <bean id="mbeanExporter" class="org.springframework.jmx.export.MBeanExporter">
        <property name="autodetect" value="true" />
        <property name="assembler" ref="jmxAssembler" />
        <property name="namingStrategy" ref="jmxNamingStrategy" />
        <property name="ensureUniqueRuntimeObjectNames" value="false" />
        <property name="excludedBeans" ref="excludedJmxBeans" />
    </bean>
    

    In your code you do something like:

    @ManagedResource(objectName = "foo.com:name=replaced", description = "...")
    public class Foo implements RuntimeJmxNames {
        ...
        public String getJmxName() {
            // here's where you can make the name be dynamic
            return toString();
        }
        @Override
        public String[] getJmxPath() {
            return new String[] { "folder" };
        }
    }
    

    Here's the Spring documentation on JMX naming although I'm not 100% sure it covers the custom naming stuff.

    Also, my SimpleJMX package does a this as well. It uses a JmxSelfNaming interface which allows each instance of an object to define it's own bean-name to make them unique and works well with Spring.

    0 讨论(0)
  • 2021-01-02 11:27

    You can do this by just implementing org.springframework.jmx.export.naming.SelfNaming:

    @Component("MyPrototypeScopedBeanName")
    @ManagedResource     
    public class MyPrototypeScopedBeanName implements SelfNaming
    {
        @Override
        public ObjectName getObjectName() throws MalformedObjectNameException {
            return new ObjectName("com.foobar", "name", this.toString());
        }
    }
    
    0 讨论(0)
提交回复
热议问题