1 /* 2 * Copyright 2002-2006 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 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 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 */ 43 public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster { 44 45 private TaskExecutor taskExecutor = new SyncTaskExecutor(); 46 47 48 /** 49 * Set the TaskExecutor to execute application listeners with. 50 * <p>Default is a SyncTaskExecutor, executing the listeners synchronously 51 * in the calling thread. 52 * <p>Consider specifying an asynchronous TaskExecutor here to not block the 53 * caller until all listeners have been executed. However, note that asynchronous 54 * execution will not participate in the caller's thread context (class loader, 55 * transaction association) unless the TaskExecutor explicitly supports this. 56 * @see org.springframework.core.task.SyncTaskExecutor 57 * @see org.springframework.core.task.SimpleAsyncTaskExecutor 58 * @see org.springframework.scheduling.timer.TimerTaskExecutor 59 */ 60 public void setTaskExecutor(TaskExecutor taskExecutor) { 61 this.taskExecutor = (taskExecutor != null ? taskExecutor : new SyncTaskExecutor()); 62 } 63 64 /** 65 * Return the current TaskExecutor for this multicaster. 66 */ 67 protected TaskExecutor getTaskExecutor() { 68 return taskExecutor; 69 } 70 71 72 public void multicastEvent(final ApplicationEvent event) { 73 for (Iterator it = getApplicationListeners().iterator(); it.hasNext();) { 74 final ApplicationListener listener = (ApplicationListener) it.next(); 75 getTaskExecutor().execute(new Runnable() { 76 public void run() { 77 listener.onApplicationEvent(event); 78 } 79 }); 80 } 81 } 82 83 } 84