Authored by wangshijie

modify error

@@ -15,7 +15,27 @@ yohobuy事件及系统监控机制的实现逻辑 @@ -15,7 +15,27 @@ yohobuy事件及系统监控机制的实现逻辑
15 #### 初始化: 15 #### 初始化:
16 16
17 在容器启动的时候,AbstractApplicationContext会首先找有没有用户配置的事件广播器ApplicationEventMulticaster,\n 17 在容器启动的时候,AbstractApplicationContext会首先找有没有用户配置的事件广播器ApplicationEventMulticaster,\n
18 -如果有则加载进来,没有则加载默认的事件广播器SimpleApplicationEventMulticaster。 18 +如果有则加载进来,没有则new一个事件广播器SimpleApplicationEventMulticaster。具体代码如下:
  19 +```java
  20 + protected void initApplicationEventMulticaster() {
  21 + ConfigurableListableBeanFactory beanFactory = getBeanFactory();
  22 + if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
  23 + this.applicationEventMulticaster =
  24 + beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
  25 + if (logger.isDebugEnabled()) {
  26 + logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
  27 + }
  28 + }
  29 + else {
  30 + this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
  31 + beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
  32 + if (logger.isDebugEnabled()) {
  33 + logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
  34 + APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
  35 + "': using default [" + this.applicationEventMulticaster + "]");
  36 + }
  37 + }
  38 +```
19 然后spring会通过反射机制将所有实现了事件监听器接口ApplicationListener的bean注册到事件广播器的监听器注册表中。 39 然后spring会通过反射机制将所有实现了事件监听器接口ApplicationListener的bean注册到事件广播器的监听器注册表中。
20 40
21 #### 事件发布和处理: 41 #### 事件发布和处理:
@@ -23,8 +43,46 @@ yohobuy事件及系统监控机制的实现逻辑 @@ -23,8 +43,46 @@ yohobuy事件及系统监控机制的实现逻辑
23 只要是实现了ApplicationEventPublisherAware接口的bean,spring会将事件发布者实际就是ApplicationContext设置到该bean中。 43 只要是实现了ApplicationEventPublisherAware接口的bean,spring会将事件发布者实际就是ApplicationContext设置到该bean中。
24 要发布事件就调用ApplicationEventPublisher的publishEvent方法,在该方法中spring会委托事件广播器发布事件。 44 要发布事件就调用ApplicationEventPublisher的publishEvent方法,在该方法中spring会委托事件广播器发布事件。
25 事件广播器会遍历注册的每个监听器,并启动来调用每个监听器的onApplicationEvent方法进行事件的处理。 45 事件广播器会遍历注册的每个监听器,并启动来调用每个监听器的onApplicationEvent方法进行事件的处理。
26 -由于默认事件广播器SimpleApplicationEventMulticaster的taskExecutor的实现类是SyncTaskExecutor,因此,事件监听器对事件的处理,是同步进行的。  
27 -要等所有监听器处理完事件才能返回。如果想用异步的,可以自己实现ApplicationEventMulticaster接口,并在Spring容器中注册id为 **applicationEventMulticaster** 的Bean。 46 +由于spring自动new的事件广播器SimpleApplicationEventMulticaster的taskExecutor为null,因此,事件监听器对事件的处理,是同步进行的。
  47 +要等所有监听器处理完事件才能返回。
  48 +```java
  49 + @Override
  50 + public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
  51 + ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
  52 + for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
  53 + Executor executor = getTaskExecutor();
  54 + if (executor != null) {
  55 + executor.execute(new Runnable() {
  56 + @Override
  57 + public void run() {
  58 + invokeListener(listener, event);
  59 + }
  60 + });
  61 + }
  62 + else {
  63 + invokeListener(listener, event);
  64 + }
  65 + }
  66 + }
  67 +
  68 + @SuppressWarnings({"unchecked", "rawtypes"})
  69 + protected void invokeListener(ApplicationListener listener, ApplicationEvent event) {
  70 + ErrorHandler errorHandler = getErrorHandler();
  71 + if (errorHandler != null) {
  72 + try {
  73 + listener.onApplicationEvent(event);
  74 + }
  75 + catch (Throwable err) {
  76 + errorHandler.handleError(err);
  77 + }
  78 + }
  79 + else {
  80 + listener.onApplicationEvent(event);
  81 + }
  82 + }
  83 +```
  84 +
  85 +如果想用异步的,可以自己实现ApplicationEventMulticaster接口,并在Spring容器中注册id为 **applicationEventMulticaster** 的Bean。
28 Spring发布一个事件之后,所有注册的事件监听器,都会收到该事件,因此,事件监听器在处理事件时,需要先判断该事件是否是自己关心的。 86 Spring发布一个事件之后,所有注册的事件监听器,都会收到该事件,因此,事件监听器在处理事件时,需要先判断该事件是否是自己关心的。
29 87
30 ### 2.yoho.core的实现 88 ### 2.yoho.core的实现