美文网首页
Spring 事件机制概述

Spring 事件机制概述

作者: 逗逗罗 | 来源:发表于2020-12-09 15:52 被阅读0次

Spring 事件机制是观察者模式的典型应用,本文将由浅入深从观察者模式、java事件机制、Spring事件机制三个部分来进行分析。

  • 观察者模式
    观察者模式是软件设计中常用的设计模式之一。定义对象间的一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生改变时,会通知所有观察者对象,使它们能够自动更新自己。观察者模式中存在两类角色:

    1. Subject 类:抽象主题类
      它把所有对观察者对象的引用保存在一个集合里,没个主题都能有任意数量的观察者。抽象主题提供接口,可以增加或删除观察者
      public interface Subject<O extends Observer> {
          void add(O o);
          void delete(O o);
          void notify();
      }
      
      
      public abstract class AbstractSubject implements Subject {
          public List<Observer> observers;
          public String state;
          public AbstractSubject() {
              this.observers = new ArrayList<>();
          }
      }
      
      // 抽象主题的具体实现,其中包含主题的状态,当状态发生改变时通知该主题所有的观察者
      public class Concrete1Subject extends AbstractSubject {
          @Override
          public void add(Observer o) {
              observers.add(o);
          }
          @Override
          public void delete(Observer o) {
              observers.remove(o);
          }
          @Override
          public void notifyObserver() {
              for(Observer o : observers) {
                  o.update(state);
              }
          }
          public void changeState(String state) {
              this.state = state;
              notifyObserver();
          }
      }
      
    2. 观察者 Observer 类:抽象观察者
      为所有具体的观察者提供接口,在得到主题的通知时执行更新操作。
      public interface Observer {
          void update(Object msg);
      }
      
      public class ConcreteObserver implements Observer {
          private String name;
          private Object oState;
          public ConcreteObserver(String name) {
              super();
              this.name = name;
          }
          @Override
          public void update(Object msg) {
              oState = msg;
              System.out.println(name + " update state to " + msg);
          }
      }
      
      public static void main(String[] args) {
          Concrete1Subject subject = new Concrete1Subject();
          ConcreteObserver observer1 = new ConcreteObserver("observer1");
          ConcreteObserver observer2 = new ConcreteObserver("observer2");
          subject.add(observer1);
          subject.add(observer2);
      
          subject.changeState("state1");
      }
      
  • Java 中的事件机制
    Java SE 中提供了事件的基础接口:EventObject 类和 EventListener 类。

    1. 事件对象:EventObject,事件对象中封装了事件源(source)

      public class EventObject implements java.io.Serializable {
          private static final long serialVersionUID = 5516075349620653480L;
          protected transient Object  source;
          public EventObject(Object source) {
              if (source == null)
                  throw new IllegalArgumentException("null source");
      
              this.source = source;
          }
          public Object getSource() {
              return source;
          }
          public String toString() {
              return getClass().getName() + "[source=" + source + "]";
          }
      }
      
    2. 事件监听:EventListener
      定义了一个事件监听器的接口,所有监听器的具体实现需要实现该接口。

      public interface EventListener {
      }
      
    3. 事件源:EventObject 中封装的事件源 source是具有行为的任何 Java 对象,其具有的行为是为了触发事件。

    三者的关系为,在事件源中注册监听器,当事件源发生某个具体的事件时,会调用监听器的方法,并将事件对象传递给监听器,同时监听器可以利用时间对象操作事件源。
    具体实现代码:

    // 1. 事件对象
    public class TestEvent extends EventObject {
        public TestEvent(Object source) {
            super(source);
        }
    }
    
    public class TestListener implements EventListener {
        public void notifyListener(EventObject eventObject) {
            if(eventObject instanceof TestEvent) {
                EventSource source = (EventSource) eventObject.getSource();
                String sourceState = source.getSourceState();
                System.out.println("source state changed to " + sourceState);
            }
        }
    }
    
    public class EventSource {
        private String sourceState = "0";
        private List<EventListener> listeners;
        public EventSource() {
            listeners = new ArrayList<>();
        }
        public EventSource(List<EventListener> listeners) {
            this.listeners = listeners;
        }
        public void addListener(EventListener eventListener) {
            listeners.add(eventListener);
        }
        public String getSourceState() {
            return sourceState;
        }
        public void setSourceState(String sourceState) {
            this.sourceState = sourceState;
        }
        public void changeState(String state) {
            sourceState = state;
            for(EventListener eventListener : listeners) {
                if(eventListener instanceof TestListener) {
                    ((TestListener) eventListener).notifyListener(new TestEvent(this));
                }
            }
        }
        public static void main(String[] args) {
            EventSource eventSource = new EventSource();
            TestListener testListener = new TestListener();
            eventSource.addListener(testListener);
    
            eventSource.changeState("1");
        }
    }
    
  • Spring 中的事件机制

    • Spring 事件机制基础
      Spring 中事件机制的支持主要包含2个顶级的接口,其作用于Java事件的两个类基本相同:ApplicationEvent, ApplicationListener。

      1. ApplicationEvent : Spring 中对事件的抽象
      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;
          }
      }
      
      1. ApplicationListener: Spring 事件的监听器
      @FunctionalInterface
      public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
          /**
          * Handle an application event.
          * @param event the event to respond to
          */
          void onApplicationEvent(E event);
      
      }
      
      1. ApplicationEventPublisher:事件发布器
        查看 ApplicationContext 的继承关系可知,其继承了 ApplicationEventPublisher 接口,因此 Spring Ioc 容器本身可以发布事件。
      @FunctionalInterface
      public interface ApplicationEventPublisher {
      
          /**
          * Notify all <strong>matching</strong> listeners registered with this
          * application of an application event. Events may be framework events
          * (such as RequestHandledEvent) or application-specific events.
          * @param event the event to publish
          * @see org.springframework.web.context.support.RequestHandledEvent
          */
          default void publishEvent(ApplicationEvent event) {
              publishEvent((Object) event);
          }
      
          /**
          * Notify all <strong>matching</strong> listeners registered with this
          * application of an event.
          * <p>If the specified {@code event} is not an {@link ApplicationEvent},
          * it is wrapped in a {@link PayloadApplicationEvent}.
          * @param event the event to publish
          * @since 4.2
          * @see PayloadApplicationEvent
          */
          void publishEvent(Object event);
      
      }
      
    • 代码实现

      1. 自定义 ApplicationEvent
      public class MySpringEvent extends ApplicationEvent {
          private String name;
          public MySpringEvent(Object source, String name) {
              super(source);
              this.name = name;
          }
          public String getName() {
              return name;
          }
          public void setName(String name) {
              this.name = name;
          }
      }
      
      1. 自定义监听器并注入至 Ioc 容器
      @Component
      public class MySpringListener implements ApplicationListener<MySpringEvent> {
      
          @Override
          public void onApplicationEvent(MySpringEvent event) {
              Object source = event.getSource();
              String name = event.getName();
              System.out.println("监听到事件 MySpringEvent,name = " + name);
          }
      }
      
      1. 测试方法
      @Configuration
      @ComponentScan("com.note.spring.listener.spring")
      public class MyConfig {
      }
      
      public static void main(String[] args) {
          ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
          applicationContext.publishEvent(new MySpringEvent("event-name1", "event"));
      }
      
  • 总结
    全文主要介绍了观察者模式、Java 事件机制、Spring 事件机制三部分的内容,并分别给出了代码实现。

    1. 观察者模式中,主要涉及了 Subject 和 Observer 两个角色, subject 中包含了对应观察者的列表,并在 subject 状态发生变化是通知所有的观察者。
    2. Java 事件机制中涉及到了两个基础类:EventObject 和 EventListener,其中 EventObject 中包含了事件源,由事件源触发 listener
    3. Spring 事件机制中包含了三个基础类: ApplicationEvent、ApplicationListener、ApplicationEventPublisher,使用时结合了 ApplicationContext 容器,后续的文章中会通过源码分析详细介绍原理。

相关文章

网友评论

      本文标题:Spring 事件机制概述

      本文链接:https://www.haomeiwen.com/subject/yyvhgktx.html