通过查询MBean获得信息只是查看应用状态的一种方法。但当应用发生重要事件时,如果希望 能够及时告知我们,这通常不是最有效的方法。

例如,假设Spittr应用保存了已发布的Spittle数量,而我们希望知道每发布一百万Spittle时的精 确时间(例如一百万、两百万、三百万等)。一种解决方法是编写代码定期查询数据库,计算Spittle的数量。但是执行这种查询会让应用和数据库都很繁忙,因为它需要不断的检查Spittle 的数量。

与重复查询数据库获得Spittle的数量相比,更好的方式是当这类事件发生时让MBean通知我 们。JMX通知(JMX notification,如图20.5 所示)是MBean与外部世界主动通信的一种方法,而 不是等待外部应用对MBean进行查询以获得信息。

Spring通过NotificationPublisherAware接口提供了发送通知的支持。任何希望发送通 知的MBean都必须实现这个接口。例如,请查看如下程序清单中的 SpittleNotifierImpl。

SpittleNotifierImpl实现了NotificationPublisherAware接口。这并不是一个要求苛刻的接口,它仅要求实现一个方 法:setNotificationPublisher。SpittleNotificationImpl也实现了SpittleNotifier接口的方 法:millionthSpittlePosted()。这个方法使用了setNotificationPublisher()方 法所注入的NotificationPublisher来发送通知,一旦sendNotification()方法被调用,就会发出通知。

package com.dxz.mvcdemo2.web.jmx.notification;

public interface SpittleNotifier {

    public void millionthSpittlePosted();
}
package com.dxz.mvcdemo2.web.jmx.notification; import javax.management.Notification; import org.springframework.jmx.export.annotation.ManagedNotification;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.jmx.export.notification.NotificationPublisher;
import org.springframework.jmx.export.notification.NotificationPublisherAware;
import org.springframework.stereotype.Component; @Component
@ManagedResource("spittle:name=SpitterNotifier")
@ManagedNotification(notificationTypes="SpitterNotifier.OneMillionSpittles", name="TODO")
public class SpittleNotificationImpl implements NotificationPublisherAware, SpittleNotifier {//实现NotificationPublisherAware接口 private NotificationPublisher notificationPublisher; //注入notificationPublisher
@Override
public void setNotificationPublisher(NotificationPublisher notificationPublisher) {
this.notificationPublisher = notificationPublisher;
} public void millionthSpittlePosted() {
//发送通知
notificationPublisher.sendNotification(new Notification("SpittleNotifier.OneMillionSpittles", this, 0));
} }

测试类:

package com.dxz.mvcdemo2.web.jmx.notification;

import static org.springframework.web.bind.annotation.RequestMethod.GET;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; @Controller
@RequestMapping("/biz5")
public class SendNotifyController { @Autowired
SpittleNotifier spittleNotifier; @RequestMapping(value = "/send", method = GET)
public void send() {
spittleNotifier.millionthSpittlePosted();
} }

启动测试:

jconsole连上JMX

点击通知:

浏览器多访问:http://localhost:8011/biz5/send 几次后,再看上面的页面变化如下:

监听通知

接收MBean通知的标准方法是实现javax.management.NotificationListener接口。 例如,考虑一下PagingNotificationListener:

package com.dxz.mvcdemo1.web.jmx.notification;

import javax.management.Notification;
import javax.management.NotificationListener; //@Component
//@ManagedResource(objectName="spittle:name=PagingNotificationListener")
public class PagingNotificationListener implements NotificationListener { @Override
public void handleNotification(Notification notification, Object handback) {
System.out.println(notification);
} }

PagingNotificationListener是一个典型的JMX通知监听器。当接收到通知时,将会调 用handleNotification()方法处理通知。大概的逻辑可能是,PagingNotificationListener的handleNotification()方法将向寻呼机或手机上发送消息来告知Spittle数 量又到了一个新的百万级别(我把实际的实现留给读者自己完成)。 剩下的工作只需要使用MBeanExporter注册PagingNotificationListener:

    @Bean
public MBeanExporter mbeanExporter() {
MBeanExporter exporter = new MBeanExporter();
/*Map<String, Object> beans = new HashMap<String, Object>();
beans.put("spittle:name=PagingNotificationListener", new PagingNotificationListener());
exporter.setBeans(beans);*/
Map<String, NotificationListener> mappings = new HashMap<String, NotificationListener>();
mappings.put("spittle:name=PagingNotificationListener", new PagingNotificationListener());
exporter.setNotificationListenerMappings(mappings); return exporter;
}

MBeanExporter的notificationListenerMappings属性用于在监听器和监听器所希 望监听的MBean之间建立映射。在本示例中,我们建立了PagingNotificationListener 来监听由SpittleNotifier MBean所发布的通知。

Spring JMX之三:通知的处理及监听的更多相关文章

  1. [Xcode 实际操作]七、文件与数据-(6 )通过通知中心,实现监听和处理程序退出事件的功能

    目录:[Swift]Xcode实际操作 本文将演示通过通知中心,实现监听和处理程序退出事件的功能. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import U ...

  2. spring与activemq(三种消息监听方式)

    1.3     消息监听器MessageListener 在Spring整合JMS的应用中我们在定义消息监听器的时候一共可以定义三种类型的消息监听器,分别是MessageListener.Sessio ...

  3. spring boot 源码赏析之事件监听

    使用spring Boot已经快1年多了,期间一直想点开springboot源码查看,但由于种种原因一直未能如愿(主要是人类的惰性...),今天就拿springboot 的监听事件祭刀. spring ...

  4. (转)spring boot实战(第三篇)事件监听源码分析

    原文:http://blog.csdn.net/liaokailin/article/details/48194777 监听源码分析 首先是我们自定义的main方法: package com.lkl. ...

  5. IOS NSNotificationCenter(通知 的使用)监听文本框的文字改变

    监听文本框的文字改变 * 一个文本输入框的文字发生改变时,文本输入框会发出一个UITextFieldTextDidChangeNotification通知 * 因此通过监听通知来监听文本输入框的文字改 ...

  6. Spring整合redis实现key过期事件监听

    打开redis服务的配置文件   添加notify-keyspace-events Ex  如果是注释了,就取消注释 这个是在以下基础上进行添加的 Spring整合redis:https://www. ...

  7. 深入理解Spring的容器内事件发布监听机制

    目录 1. 什么是事件监听机制 2. JDK中对事件监听机制的支持 2.1 基于JDK实现对任务执行结果的监听 3.Spring容器对事件监听机制的支持 3.1 基于Spring实现对任务执行结果的监 ...

  8. rabbitMq与spring boot搭配实现监听

    在我前面有一篇博客说到了rabbitMq实现与zk类似的watch功能,但是那一篇博客没有代码实例,后面自己补了一个demo,便于理解.demo中主要利用spring boot的配置方式, 一.消费者 ...

  9. Spring Boot实践——事件监听

    借鉴:https://blog.csdn.net/Harry_ZH_Wang/article/details/79691994 https://blog.csdn.net/ignorewho/arti ...

随机推荐

  1. 利用Web Services开发分布式应用

    一.引言 在前面文章中分别介绍了MSMQ和.NET Remoting技术,今天继续分享.NET 平台下另一种分布式技术——Web Services 二.Web Services 详细介绍 2.1 We ...

  2. php浮点数比较

    本文实例讲述了PHP中两个float(浮点数)比较方法.分享给大家供大家参考.具体如下: 最近在开发一个合同管理系统的时候,涉及到两个浮点数比较,算是把我郁闷惨了.在N久以前,就不晓得从哪里听来的一个 ...

  3. FastAdmin 中 的 layer js 使用 r.js 压缩出现的问题

    FastAdmin 中 的 layer js 使用 r.js 压缩出现的问题 https://fly.layui.com/jie/2120/ layer是requirejs压缩文件r.js里面的关键字 ...

  4. emacs之配置之初始目录设置

    emacsConfig/dir-setting.el (setq default-directory "~/" )

  5. emacs之配置代码风格

    emacsConfig/code-style-setting.el (add-hook 'c-mode-common-hook ( lambda() ( c-set-style "java& ...

  6. try catch finally ,try 中有return时怎么执行

  7. 关于 android 环信无法正确获取昵称的问题

    本案例中 username 记录成 userId了, nick 始终为空...,这是 getNick() 取得的就是 username..... 如果想自己取得自己系统的nickname则 做以下调整 ...

  8. Java 经典练习题_Day010

    final 变量能被显式地初始化并且只能初始化一次.被声明为 final 的对象的引用不能指向不同的对象.但是 final 对象里的数据可以被改变.也就是说 final 对象的引用不能改变,但是里面的 ...

  9. 二货Mysql中设置字段的默认值问题

    Mysql设置字段的默认值的确很落伍 1.不支持函数 2.只支持固定常量. 经常用到的日期类型,因为不支持getdate或者now函数,所以只能设置timestamp类型 而且还必须在默认值那个地方写 ...

  10. Linux nohup和&的功效

    nohup和&究竟有啥区别?不少同学进行了回复,但并不是所有同学都理解得全对,今天把自己挖的坑自己填了. 测试代码如下: 是一个输出hello与循环轮数的死循环程序,每输出一行就休眠1秒. 使 ...