Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exporting Spring @Bean objects using JMX

I'm using Spring's @Configuration, and I noticed that a @Bean does not get registered using JMX.

The bean is wired as

@Bean
protected CountingHttpInterceptor countingHttpInterceptor() {

    return new CountingHttpInterceptor();
}

and the class definition is

@ManagedResource
public class CountingHttpInterceptor implements HttpRequestInterceptor, HttpResponseInterceptor { /* code here*/ }

This @Configuration file is processed after the main , XML-based, application context is built, and does not have the chance to take part in the discovery process which is activated using XML bean definitions ( org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource and frieds ).

How can I JMX-enable the beans from the @Configuration file?


Update: the xml configuration

<bean id="jmxExporter" class="org.springframework.jmx.export.MBeanExporter">
    <property name="assembler" ref="assembler"/>
    <property name="namingStrategy" ref="namingStrategy"/>
    <property name="autodetect" value="true"/>
</bean>

<bean id="jmxAttributeSource" class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/>

<bean id="assembler" class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
    <property name="attributeSource" ref="jmxAttributeSource"/>
</bean>

<bean id="namingStrategy" class="org.springframework.jmx.export.naming.MetadataNamingStrategy">
    <property name="attributeSource" ref="jmxAttributeSource"/>
</bean>
like image 576
Robert Munteanu Avatar asked Jan 21 '23 20:01

Robert Munteanu


1 Answers

Despite the temptations of the @Configuration- based approach, some things remain better done with XML config. In particular, the namespace-based config such as <context:mbean-export>. These essentially represent "macros" consisting of complex arrangements of interacting objects.

Now, you could replicate this logic in your @Configuration class, but it's really more trouble than it's worth. Instead, I suggest putting such system-level stuff into XML, and importing it from your @Configuration class:

@ImportResource("/path/to/beans.xml")
public class MyConfig {
   @Bean
   protected CountingHttpInterceptor countingHttpInterceptor() {
      return new CountingHttpInterceptor();
   }
}

and then in /path/to/beans.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans
           xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="
               http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
           ">  

    <context:mbean-export/>
</beans>
like image 51
skaffman Avatar answered Feb 01 '23 23:02

skaffman