Spring provides a nice way to expose plain java objects and its
methods and properties as JMX managed objects. Maybe the best way to do
so is using annotations.
@ManagedResource( objectName = "domain:name=testBean", description = "A test Spring-JMX bean") public class JmxTestBean { private int age; private String name; @ManagedAttribute(description = "age attribute") public void setAge(int age) { logger.info("setAge"); this.age = age; } @ManagedAttribute(description = "age attribute") public int getAge() { logger.info("getAge"); return age; } @ManagedAttribute(description = "name attribute") public void setName(String name) { logger.info("setNamee"); this.name = name; } @ManagedAttribute(description = "name attribute") public String getName() { logger.info("getName"); return name; } public String dontExposeThisMethod() { return "dontExposeThisMethod return"; } @ManagedOperation(description = "method exposed") public String exposeThisMethod() { return "exposeThisMethod return"; } }
In the application context you need
<bean id="jmxAdapter.parent" class="org.springframework.jmx.export.MBeanExporter" abstract="true"> <property name="autodetect"> <value>true</value> </property> <property name="assembler"> <ref local="metadataMBeanInfoAssembler"/> </property> <property name="namingStrategy"> <ref local="namingStrategy"/> </property> </bean> <!-- Use metadata to filter the exposed operations and attributes --> <bean id="metadataMBeanInfoAssembler" class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler"> <property name="attributeSource"> <ref local="annotationJmxAttributeSource"/> </property> </bean> <bean id="annotationJmxAttributeSource" class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/> <bean id="namingStrategy" class="org.springframework.jmx.export.naming.MetadataNamingStrategy"> <property name="attributeSource"> <ref local="annotationJmxAttributeSource"/> </property> </bean> <bean id="testBean" class="com.arcmind.springjmx.JmxTestBean"> <property name="name"> <value>TEST</value> </property> <property name="age"> <value>100</value> </property> </bean>
For testing you’d need to explicitly set the mbean server
<bean id="jmxAdapter" parent="jmxAdapter.parent"> <property name="server"> <ref local="mbeanServer"/> </property> </bean> <bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean"/>
For deploying it gets autodetected
<bean id="jmxAdapter" parent="jmxAdapter.parent"/>
Other options for the assembler property are
<!-- Expose everything through reflection --> <bean id="simpleReflectiveMBeanInfoAssembler" class="org.springframework.jmx.export.assembler.SimpleReflectiveMBeanInfoAssembler"/> <!-- Use method names to filter the exposed operations and attributes --> <bean id="methodNameBasedMBeanInfoAssembler" class="org.springframework.jmx.export.assembler.MethodNameBasedMBeanInfoAssembler"> <property name="managedMethods"> <list> <value>exposeThisMethod</value> <value>getAge</value> <value>setAge</value> <value>getName</value> <value>setName</value> </list> </property> </bean> <!-- Expose only those methods in the interfaces implemented by the bean --> <bean id="interfaceBasedMBeanInfoAssembler" class="org.springframework.jmx.export.assembler.InterfaceBasedMBeanInfoAssembler"/>
But then you may need to explicitly say what beans you want to
expose instead of autodetecting them in the jmxAdapter.parent bean.
<property name="beans"> <map> <entry key="bean:name=testBean1"> <ref local="testBean"/> </entry> </map> </property>