zoukankan      html  css  js  c++  java
  • spring事件驱动模型--观察者模式在spring中的应用

    spring事件驱动模型--观察者模式在spring中的应用

     

      spring中的事件驱动模型也叫作发布订阅模式,是观察者模式的一个典型的应用,关于观察者模式在之前的博文中总结过,http://www.cnblogs.com/fingerboy/p/5468994.html  这里主要讲一下Spring中的观察者模式的应用.

    spring事件驱动模型的结构.

      

      首先明确几个spring提供的类的概念

      1.ApplicationEvent

    复制代码
    public abstract class ApplicationEvent extends EventObject {
        private static final long serialVersionUID = 7099057708183571937L;
        private final long timestamp;
        public ApplicationEvent(Object source) {
            super(source);
            this.timestamp = System.currentTimeMillis();
        }
        public final long getTimestamp() {
            return this.timestamp;
        }
    }
    复制代码

      ApplicationEvent继承自jdk的EventObject,所有的事件都需要继承ApplicationEvent,并且通过source得到事件源.该类的实现类ApplicationContextEvent表示ApplicaitonContext的容器事件.

      2.ApplicationListener

    public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
        void onApplicationEvent(E event);
    }

      ApplicationListener继承自jdk的EventListener,所有的监听器都要实现这个接口,这个接口只有一个onApplicationEvent()方法,该方法接受一个ApplicationEvent或其子类对象作为参数,在方法体中,可以通过不同对Event类的判断来进行相应的处理.当事件触发时所有的监听器都会收到消息,如果你需要对监听器的接收顺序有要求,可是实现该接口的一个实现SmartApplicationListener,通过这个接口可以指定监听器接收事件的顺序.

      3.ApplicationContext

       事件机制的实现需要三个部分,事件源,事件,事件监听器,在上面介绍的ApplicationEvent就相当于事件,ApplicationListener相当于事件监听器,这里的事件源说的就是applicaitonContext.

       ApplicationContext是spring中的全局容器,翻译过来是"应用上下文"的意思,它用来负责读取bean的配置文档,管理bean的加载,维护bean之间的依赖关系,可以说是负责bean的整个生命周期,再通俗一点就是我们平时所说的IOC容器. 

          Application作为一个事件源,需要显示的调用publishEvent方法,传入一个ApplicationEvent的实现类对象作为参数,每当ApplicationContext发布ApplicationEvent时,所有的ApplicationListener就会被自动的触发.

      ApplicationContext接口实现了ApplicationEventPublisher接口,后者有一个很重要的方法:

    public interface ApplicationEventPublisher {
        void publishEvent(ApplicationEvent event);
    }

      我们常用的ApplicationContext都继承了AbstractApplicationContext,像我们平时常见的ClassPathXmlApplicationContext、XmlWebApplicationContex也都是继承了它,AbstractApplicationcontext是ApplicationContext接口的抽象实现类,在该类中实现了publishEvent方法

    复制代码
    public void publishEvent(ApplicationEvent event) {
            Assert.notNull(event, "Event must not be null");
            if (logger.isTraceEnabled()) {
                logger.trace("Publishing event in " + getDisplayName() + ": " + event);
            }
            getApplicationEventMulticaster().multicastEvent(event);
            if (this.parent != null) {
                this.parent.publishEvent(event);
            }
        }
    复制代码

      在这个方法中,我们看到了一个getApplicationEventMulticaster().这就要牵扯到另一个类ApplicationEventMulticaster.

      4.ApplicationEventMulticaster

      属于事件广播器,它的作用是把Applicationcontext发布的Event广播给所有的监听器.

      在AbstractApplicationcontext中有一个applicationEventMulticaster的成员变量,提供了监听器Listener的注册方法.

    复制代码
    public abstract class AbstractApplicationContext extends DefaultResourceLoader
            implements ConfigurableApplicationContext, DisposableBean {
    
      private ApplicationEventMulticaster applicationEventMulticaster;
      protected void registerListeners() {
            // Register statically specified listeners first.
            for (ApplicationListener<?> listener : getApplicationListeners()) {
                getApplicationEventMulticaster().addApplicationListener(listener);
            }
            // Do not initialize FactoryBeans here: We need to leave all regular beans
            // uninitialized to let post-processors apply to them!
            String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
            for (String lisName : listenerBeanNames) {
                getApplicationEventMulticaster().addApplicationListenerBean(lisName);
            }
        }
    }
    复制代码

     在Spring 中使用事件监听机制的Demo

      1. 建立事件类,继承applicationEvent

    复制代码
    public class MyEvent extends ApplicationEvent {
    
        public MyEvent(Object source) {
            super(source);
            System.out.println("my Event");
        }
        public void print(){
            System.out.println("hello spring event[MyEvent]");
        }
    }
    复制代码

      2.建立监听类,实现ApplicationListener接口

    复制代码
    public class MyListener  implements ApplicationListener{
        
        public void onApplicationEvent(ApplicationEvent event) {
            if(event instanceof MyEvent){
                System.out.println("into My Listener");
                MyEvent myEvent=(MyEvent)event;
                myEvent.print();
            }
        }
    }
    复制代码

    这里再建一个监听类

    复制代码
    public class MyListener  implements ApplicationListener{
        
        public void onApplicationEvent(ApplicationEvent event) {
            if(event instanceof MyEvent){
                System.out.println("into My Listener");
                MyEvent myEvent=(MyEvent)event;
                myEvent.print();
            }
        }
    }
    复制代码

      3.创建一个发布事件的类,该类实现ApplicationContextAware接口,得到ApplicationContext对象,使用该对象的publishEvent方法发布事件.

    复制代码
    public class MyPubisher implements ApplicationContextAware {
    
        private ApplicationContext applicationContext;
        
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.applicationContext=applicationContext;
        }
        public void publishEvent(ApplicationEvent event){
            System.out.println("into My Publisher's method");
            applicationContext.publishEvent(event);
        }
    }
    复制代码

      3.在spring配置文件中,注册事件类和监听类,当然使用注解的方式也是一样的.(略)

      4.测试

    复制代码
    public class MyTest {
        public static void main(String[] args) {
            ApplicationContext context=new ClassPathXmlApplicationContext("classpath:spring/application-database.xml");
            MyPubisher myPubisher=(MyPubisher) context.getBean("myPublisher");
            myPubisher.publishEvent(new MyEvent("1"));
        }
    }
    复制代码
  • 相关阅读:
    iOS离屏渲染简书
    iOS Waxpatch项目(动态更新)
    waxpatch修改任意类的用法
    ios waxpatch lua语法
    ios WaxPatch热更新原理
    WaxPatch中demo注意问题
    ios wax热更新之安装wax(xcode7.3.1)
    获取第三方键盘高度(包括自带键盘高度)
    25个增强iOS应用程序性能的提示和技巧(高级篇)(2)
    JS基础_一元运算符
  • 原文地址:https://www.cnblogs.com/leigepython/p/11049515.html
Copyright © 2011-2022 走看看