zoukankan      html  css  js  c++  java
  • Spring JMX之三:通知的处理及监听

    通过查询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所发布的通知。

  • 相关阅读:
    tfrecord汇总
    python2中的编码的问题
    python multiprocessing的问题
    转载,ubuntu shell ~/.bashrc /etc/bash.bashrc
    singleton模式 Python
    目标检测 tensorflow(预训练模型)
    functools.partial 小记
    python 踩坑小计 virtualenv-site-packages
    python3.6 _tkinter module问题 python源码重新编译
    windows核心编程之网络编程入门篇
  • 原文地址:https://www.cnblogs.com/duanxz/p/4036619.html
Copyright © 2011-2022 走看看