编程语言
首页 > 编程语言> > Spring源码之事件管理与发布

Spring源码之事件管理与发布

作者:互联网

        在AbstractApplicationContext.refresh() 方法中,初始化了一个事件管理类(或事件管理器)。

// Initialize event multicaster for this context.
// TODO 初始化事件管理类,在单例池中创建了一个SimpleApplicationEventMulticaster类
initApplicationEventMulticaster();

进入 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.isTraceEnabled()) {
         logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
      }
   }
   else {
      // 在这new了一个SimpleApplicationEventMulticaster事件管理类
      SimpleApplicationEventMulticaster simpleApplicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
      simpleApplicationEventMulticaster.setApplicationStartup(getApplicationStartup());
      this.applicationEventMulticaster = simpleApplicationEventMulticaster;
      // 把这个事件管理类注册到beanFactory中
      beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
      if (logger.isTraceEnabled()) {
         logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
               "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
      }
   }
}

回到refresh() 方法,这里有一个registerListeners() 方法:

// Check for listener beans and register them.
// 往事件管理类中注册事件类,核心代码在这里
registerListeners();

进入 registerListeners() 方法:

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!
		// 从beanFactory中拿到一个ApplicationListener的实例
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			// 把这个BeanName加入到事件观察者(监听)容器applicationListenerBeans中,
			// 当事件发布时通知这些观察者
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}

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

事件发布真正调用的方法是 AbstractApplicationContext.publishEvent() 方法,

该方法是ApplicationEventPublisher接口的方法,AbstractApplicationContext进行了重写:

@Override
public void publishEvent(ApplicationEvent event) {
   // 事件发布
   publishEvent(event, null);
}

进入publishEvent() 方法:

	protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
		Assert.notNull(event, "Event must not be null");

		// Decorate event as an ApplicationEvent if necessary
		ApplicationEvent applicationEvent;
		if (event instanceof ApplicationEvent) {
			applicationEvent = (ApplicationEvent) event;
		}
		else {
			applicationEvent = new PayloadApplicationEvent<>(this, event);
			if (eventType == null) {
				eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
			}
		}

		// Multicast right now if possible - or lazily once the multicaster is initialized
		if (this.earlyApplicationEvents != null) {
			this.earlyApplicationEvents.add(applicationEvent);
		}
		else {
			// TODO 拿到事件管理类,里面管理了多个观察者
			getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
		}

		// Publish event via parent context as well...
		if (this.parent != null) {
			if (this.parent instanceof AbstractApplicationContext) {
				((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
			}
			else {
				this.parent.publishEvent(event);
			}
		}
	}

进入multicastEvent() 方法:

所属类:org.springframework.context.event.SimpleApplicationEventMulticaster

public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
   ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
   Executor executor = getTaskExecutor();
   for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
      if (executor != null) {
         executor.execute(() -> invokeListener(listener, event));
      }
      else if (this.applicationStartup != null) {
         StartupStep invocationStep = this.applicationStartup.start("spring.event.invoke-listener");
         invokeListener(listener, event);
         invocationStep.tag("event", event::toString);
         if (eventType != null) {
            invocationStep.tag("eventType", eventType::toString);
         }
         invocationStep.tag("listener", listener::toString);
         invocationStep.end();
      }
      else {
         // 调用Listener,通知监听者
         invokeListener(listener, event);
      }
   }
}

进入invokeListener() 方法:

所属类:org.springframework.context.event.SimpleApplicationEventMulticaster

protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
   ErrorHandler errorHandler = getErrorHandler();
   if (errorHandler != null) {
      try {
         // 着重看这里
         doInvokeListener(listener, event);
      }
      catch (Throwable err) {
         errorHandler.handleError(err);
      }
   }
   else {
      doInvokeListener(listener, event);
   }
}

进入doInvokeListener() 方法:

所属类:org.springframework.context.event.SimpleApplicationEventMulticaster

private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
   try {
      // 去调用所有事件管理者的onApplicationEvent()方法,
      // 自定义监听者实现了ApplicationListener接口,会重写onApplicationEvent()方法
      listener.onApplicationEvent(event);
   }
   catch (ClassCastException ex) {
      String msg = ex.getMessage();
      if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
         // Possibly a lambda-defined listener which we could not resolve the generic event type for
         // -> let's suppress the exception and just log a debug message.
         Log logger = LogFactory.getLog(getClass());
         if (logger.isTraceEnabled()) {
            logger.trace("Non-matching event type for listener: " + listener, ex);
         }
      }
      else {
         throw ex;
      }
   }
}

应用举例:

1.自定义事件类,须继承ApplicationEvent:

/**
 * @ClassName: OrderCreateEvent
 * @Description: 订单创建活动事件
 * @Author: Kaisheng Du
 * @Date: 2021/9/22 13:52
 * @Version: 1.0
 */
public class OrderCreateEvent extends ApplicationEvent {

    private String name;

    //消息参数
    private List<String> contentList;

    public OrderCreateEvent(Object source, String name, List<String> contentList) {
        super(source);
        this.name = name;
        this.contentList = contentList;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<String> getContentList() {
        return contentList;
    }

    public void setContentList(List<String> contentList) {
        this.contentList = contentList;
    }

}

2. 自定义事件监听类(可以定义多个):

/**
 * @ClassName: SmsListener
 * @Description: 短信监听器
 * @Author: Kaisheng Du
 * @Date: 2021/9/22 13:55
 * @Version: 1.0
 */
@Component
public class SmsListener implements ApplicationListener<OrderCreateEvent> {

    @Override
    public void onApplicationEvent(OrderCreateEvent event) {
        //发送短信
        System.out.println(event.getContentList().get(0) + ",您的订单:" + event.getContentList().get(1) + "创建成功! ----by sms");
    }
}
/**
 * @ClassName: SmsListener
 * @Description: 微信监听器
 * @Author: Kaisheng Du
 * @Date: 2021/9/22 13:55
 * @Version: 1.0
 */
@Component
public class WechatListener implements ApplicationListener<OrderCreateEvent> {

    @Override
    public void onApplicationEvent(OrderCreateEvent event) {
        //发送微信
        System.out.println(event.getContentList().get(0) + ",您的订单:" + event.getContentList().get(1) + "创建成功! ----by wechat");
    }
}

3.事件发布

public interface OrderService {

    void saveOrder();
}
/**
 * @ClassName: OrderServiceImpl
 * @Description: 保存订单后发送通知
 * @Author: Kaisheng Du
 * @Date: 2021/9/22 13:50
 * @Version: 1.0
 */
@Service
public class OrderServiceImpl implements OrderService {

    @Resource
    private ApplicationContext applicationContext;
    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;

    @Override
    public void saveOrder() {
        // 1.创建订单
        System.out.println("订单创建成功");
        // 2.发布事件
        ArrayList<String> contentList = new ArrayList<>();
        contentList.add("kieasar");
        contentList.add("123456789");
        OrderCreateEvent orderCreateEvent = new OrderCreateEvent(this, "订单创建", contentList);
        // ApplicationContext是我们的事件容器上层,我们发布事件,也可以通过此容器完成发布
        applicationContext.publishEvent(orderCreateEvent);
        // 也可以通过下面方法进行事件发布
//        applicationEventPublisher.publishEvent(orderCreateEvent);
    }

    class Person{

    }
}

案例测试:

    @Test
    public void testEvent() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ScanBean.class);
        OrderService orderService = (OrderService) applicationContext.getBean("orderServiceImpl");
        // 调用保存订单方法
        orderService.saveOrder();
    }

标签:contentList,Spring,void,event,listener,源码,事件,null,public
来源: https://blog.csdn.net/qq_40213907/article/details/120670274