Showing
1 changed file
with
61 additions
and
3 deletions
@@ -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的实现 |
-
Please register or login to post a comment