Spring 源码解析 ---- 事件监听

一. 测试用例

package main.java.com.wenniuwuren.spring.event.listener;


import org.springframework.context.ApplicationEvent;

/**
 * 定义监听事件
 * Created by hzzhuyibin on 2016/11/22.
 */
public class TestEvent extends ApplicationEvent {

public String msg;

 /**
 * Create a new ApplicationEvent.
 *
 * @param source the object on which the event initially occurred (never {@code null})
 */
 public TestEvent(Object source) {
super(source);
 }

public TestEvent(Object source, String msg) {
super(source);
 this.msg = msg;
 }

public void print() {
System.out.println(msg);
 }

}

package main.java.com.wenniuwuren.spring.event.listener;

import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;

/**
 * 定义监听器
 * Created by hzzhuyibin on 2016/11/22.
 */
public class TestListener implements ApplicationListener{
@Override
 public void onApplicationEvent(ApplicationEvent event) {

if (event instanceof TestEvent) {
TestEvent testEvent = (TestEvent)event;
 testEvent.print();
 }
}
}

listenerTest.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean name="testListener" class="main.java.com.wenniuwuren.spring.event.listener.TestListener"/>

</beans>

测试类:

package main.java.com.wenniuwuren.spring.event.listener;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 *
 * Created by Yibin_Zhu on 2016/11/21.
 */
public class Test{

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("main/resources/listenerTest.xml");
        // 不仅仅可以指定 beanName,也可以有构造函数或者工厂方法的方法参数

        TestEvent testEvent = new TestEvent("hello", "wenniuwuren");

        context.publishEvent(testEvent);

    }
}

二. 源码解析 debug 到 AbstractApplicationContext 类的 initApplicationEventMulticaster() 方法

广播器我们又经常成为事件

protected void initApplicationEventMulticaster() {
   ConfigurableListableBeanFactory beanFactory = getBeanFactory();
   // 用户自定义事件广播器
   if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
      this.applicationEventMulticaster =
            beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
      if (logger.isDebugEnabled()) {
         logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
      }
   }
   else { // 默认事件广播器
      this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
      beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
      if (logger.isDebugEnabled()) {
         logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
               APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
               "': using default [" + this.applicationEventMulticaster + "]");
      }
   }
}

我们关注的是 SimpleApplicationEventMulticaster 事件类的具体实现,继续 debug 进去,看到此类继承自 AbstractApplicationEventMulticaster, 而 AbstractApplicationEventMulticaster 中有许多 add**Listener、delete**Listener 之类的方法,可以知道这是典型的
观察者模式的应用。

继续看如下方法:事件在这里广播,遍历所有监听器,通知监听器

@Override
public void multicastEvent(ApplicationEvent event) {
   multicastEvent(event, resolveDefaultEventType(event));
}

@Override
public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
   ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
   for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
      Executor executor = getTaskExecutor();
      if (executor != null) {
         executor.execute(new Runnable() {
            @Override
            public void run() {
               invokeListener(listener, event);
            }
         });
      }
      else {
         invokeListener(listener, event);
      }
   }
}

protected void invokeListener(ApplicationListener listener, ApplicationEvent event) {
   ErrorHandler errorHandler = getErrorHandler();
   if (errorHandler != null) {
      try {
         listener.onApplicationEvent(event);
      }
      catch (Throwable err) {
         errorHandler.handleError(err);
      }
   }
   else {
      listener.onApplicationEvent(event);
   }
}

这个方法 debug 结束,回到 AbstractApplicationContext 类,debug 进 registerListeners() 方法:注册监听器

protected void registerListeners() {
   // 硬编码的方式注册监听器
   for (ApplicationListener<?> listener : getApplicationListeners()) {
      getApplicationEventMulticaster().addApplicationListener(listener);
   }

   // 配置文件注册监听器
   String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
   for (String listenerBeanName : listenerBeanNames) {
      getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
   }

   // Publish early application events now that we finally have a multicaster...
   Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
   this.earlyApplicationEvents = null;
   if (earlyEventsToProcess != null) {
      for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
         getApplicationEventMulticaster().multicastEvent(earlyEvent);
      }
   }
}


    原文作者:Spring Boot
    原文地址: https://blog.csdn.net/wenniuwuren/article/details/53301520
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞