01: /*
02: * Copyright 2002-2007 the original author or authors.
03: *
04: * Licensed under the Apache License, Version 2.0 (the "License");
05: * you may not use this file except in compliance with the License.
06: * You may obtain a copy of the License at
07: *
08: * http://www.apache.org/licenses/LICENSE-2.0
09: *
10: * Unless required by applicable law or agreed to in writing, software
11: * distributed under the License is distributed on an "AS IS" BASIS,
12: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13: * See the License for the specific language governing permissions and
14: * limitations under the License.
15: */
16:
17: package org.springframework.context.event;
18:
19: import java.util.Iterator;
20:
21: import org.springframework.context.ApplicationEvent;
22: import org.springframework.context.ApplicationListener;
23: import org.springframework.core.task.SyncTaskExecutor;
24: import org.springframework.core.task.TaskExecutor;
25:
26: /**
27: * Simple implementation of the {@link ApplicationEventMulticaster} interface.
28: *
29: * <p>Multicasts all events to all registered listeners, leaving it up to
30: * the listeners to ignore events that they are not interested in.
31: * Listeners will usually perform corresponding <code>instanceof</code>
32: * checks on the passed-in event object.
33: *
34: * <p>By default, all listeners are invoked in the calling thread.
35: * This allows the danger of a rogue listener blocking the entire application,
36: * but adds minimal overhead. Specify an alternative TaskExecutor to have
37: * listeners executed in different threads, for example from a thread pool.
38: *
39: * @author Rod Johnson
40: * @author Juergen Hoeller
41: * @see #setTaskExecutor
42: * @see #setConcurrentUpdates
43: */
44: public class SimpleApplicationEventMulticaster extends
45: AbstractApplicationEventMulticaster {
46:
47: private TaskExecutor taskExecutor = new SyncTaskExecutor();
48:
49: /**
50: * Set the TaskExecutor to execute application listeners with.
51: * <p>Default is a SyncTaskExecutor, executing the listeners synchronously
52: * in the calling thread.
53: * <p>Consider specifying an asynchronous TaskExecutor here to not block the
54: * caller until all listeners have been executed. However, note that asynchronous
55: * execution will not participate in the caller's thread context (class loader,
56: * transaction association) unless the TaskExecutor explicitly supports this.
57: * @see org.springframework.core.task.SyncTaskExecutor
58: * @see org.springframework.core.task.SimpleAsyncTaskExecutor
59: * @see org.springframework.scheduling.timer.TimerTaskExecutor
60: */
61: public void setTaskExecutor(TaskExecutor taskExecutor) {
62: this .taskExecutor = (taskExecutor != null ? taskExecutor
63: : new SyncTaskExecutor());
64: }
65:
66: /**
67: * Return the current TaskExecutor for this multicaster.
68: */
69: protected TaskExecutor getTaskExecutor() {
70: return this .taskExecutor;
71: }
72:
73: public void multicastEvent(final ApplicationEvent event) {
74: for (Iterator it = getApplicationListeners().iterator(); it
75: .hasNext();) {
76: final ApplicationListener listener = (ApplicationListener) it
77: .next();
78: getTaskExecutor().execute(new Runnable() {
79: public void run() {
80: listener.onApplicationEvent(event);
81: }
82: });
83: }
84: }
85:
86: }
|