Publish JMX notifications in using Spring without NotificationPublisherAware
I'd like to publish JMX notifications using Spring 3, but would like to avoid using the NotificationPublisherAware interface, since the code is also used by an application that doesn't use Spring. The bean is exposed using MBeanExporter bean. The alte开发者_如何转开发rnatives I found require registering the mbeans, which I currently do using Spring configuration, so this is a bad option. Is there a way to avoid using the NotificationPublisherAware interface but still publish notifications?
You don't have to use any Spring class in code. Example:
Interface:
import javax.management.MXBean;
@MXBean
public interface SecurityEventsManagerMXBean {
...
@AttributeMetaData(value="UserLoginFailures", defaultValue="0", description="Total user login failures")
public int getUserLoginFailureCount() ;
...
}
Bean:
import javax.management.Notification;
import javax.management.NotificationBroadcasterSupport;
public class SecurityEventsManager extends NotificationBroadcasterSupport implements SecurityEventsManagerMXBean {
...
private void notifyUserLoginFailure(...) {
Notification notification = new Notification(...) ;
sendNotification(notification)
userLoginFailureCount++ ;
}
}
Here @AttributeMetaData is a convenient meta annotation that defines descriptor keys:
import javax.management.DescriptorKey;
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AttributeMetaData {
@DescriptorKey("displayName")
String value();
....
}
Edit March 08. Configuration to export above Mbean:
<bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean"
p:locateExistingServerIfPossible="true" />
<bean id="jmxAttributeSource" class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/>
<bean id="namingStrategy" class="org.springframework.jmx.export.naming.MetadataNamingStrategy"
p:attributeSource-ref="jmxAttributeSource" />
<bean id="assembler" class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler"
p:attributeSource-ref="jmxAttributeSource" />
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
<property name="server" ref="mbeanServer"/>
<property name="assembler" ref="assembler"/>
<property name="registrationBehaviorName" value="REGISTRATION_FAIL_ON_EXISTING"/>
<property name="beans">
<map>
<entry>
<key>
<util:constant
static-field="x.y.z.SecurityEventsManager.OBJECT_NAME" />
</key>
<ref bean="securityEventsManager" />
</entry>
</map>
</property>
</bean>
<bean id="securityEventsManager" class="x.y.z.SecurityEventsManager" />
As per Spring docs:
The NotificationPublisher interface and the machinery to get it all working is one of the nicer features of Spring's JMX support. It does however come with the price tag of coupling your classes to both Spring and JMX; as always, the advice here is to be pragmatic... if you need the functionality offered by the NotificationPublisher and you can accept the coupling to both Spring and JMX, then do so.
Ref: http://static.springsource.org/spring/docs/3.0.0.M3/reference/html/ch24s07.html#jmx-notifications-listeners
精彩评论