Package org.springframework.context.event

Source Code of org.springframework.context.event.SimpleApplicationEventMulticaster

/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.context.event;

import java.util.concurrent.Executor;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.util.ErrorHandler;

/**
* Simple implementation of the {@link ApplicationEventMulticaster} interface.
*
* <p>Multicasts all events to all registered listeners, leaving it up to
* the listeners to ignore events that they are not interested in.
* Listeners will usually perform corresponding {@code instanceof}
* checks on the passed-in event object.
*
* <p>By default, all listeners are invoked in the calling thread.
* This allows the danger of a rogue listener blocking the entire application,
* but adds minimal overhead. Specify an alternative task executor to have
* listeners executed in different threads, for example from a thread pool.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @see #setTaskExecutor
*/
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {

  private Executor taskExecutor;

  private ErrorHandler errorHandler;


  /**
   * Create a new SimpleApplicationEventMulticaster.
   */
  public SimpleApplicationEventMulticaster() {
  }

  /**
   * Create a new SimpleApplicationEventMulticaster for the given BeanFactory.
   */
  public SimpleApplicationEventMulticaster(BeanFactory beanFactory) {
    setBeanFactory(beanFactory);
  }


  /**
   * Set a custom executor (typically a {@link org.springframework.core.task.TaskExecutor})
   * to invoke each listener with.
   * <p>Default is equivalent to {@link org.springframework.core.task.SyncTaskExecutor},
   * executing all listeners synchronously in the calling thread.
   * <p>Consider specifying an asynchronous task executor here to not block the
   * caller until all listeners have been executed. However, note that asynchronous
   * execution will not participate in the caller's thread context (class loader,
   * transaction association) unless the TaskExecutor explicitly supports this.
   * @see org.springframework.core.task.SyncTaskExecutor
   * @see org.springframework.core.task.SimpleAsyncTaskExecutor
   */
  public void setTaskExecutor(Executor taskExecutor) {
    this.taskExecutor = taskExecutor;
  }

  /**
   * Return the current task executor for this multicaster.
   */
  protected Executor getTaskExecutor() {
    return this.taskExecutor;
  }

  /**
   * Set the {@link ErrorHandler} to invoke in case an exception is thrown
   * from a listener.
   * <p>Default is none, with a listener exception stopping the current
   * multicast and getting propagated to the publisher of the current event.
   * If a {@linkplain #setTaskExecutor task executor} is specified, each
   * individual listener exception will get propagated to the executor but
   * won't necessarily stop execution of other listeners.
   * <p>Consider setting an {@link ErrorHandler} implementation that catches
   * and logs exceptions (a la
   * {@link org.springframework.scheduling.support.TaskUtils#LOG_AND_SUPPRESS_ERROR_HANDLER})
   * or an implementation that logs exceptions while nevertheless propagating them
   * (e.g. {@link org.springframework.scheduling.support.TaskUtils#LOG_AND_PROPAGATE_ERROR_HANDLER}).
   * @since 4.1
   */
  public void setErrorHandler(ErrorHandler errorHandler) {
    this.errorHandler = errorHandler;
  }

  /**
   * Return the current error handler for this multicaster.
   * @since 4.1
   */
  protected ErrorHandler getErrorHandler() {
    return this.errorHandler;
  }


  @Override
  public void multicastEvent(final ApplicationEvent event) {
    for (final ApplicationListener<?> listener : getApplicationListeners(event)) {
      Executor executor = getTaskExecutor();
      if (executor != null) {
        executor.execute(new Runnable() {
          @Override
          public void run() {
            invokeListener(listener, event);
          }
        });
      }
      else {
        invokeListener(listener, event);
      }
    }
  }

  /**
   * Invoke the given listener with the given event.
   * @param listener the ApplicationListener to invoke
   * @param event the current event to propagate
   * @since 4.1
   */
  @SuppressWarnings({"unchecked", "rawtypes"})
  protected void invokeListener(ApplicationListener listener, ApplicationEvent event) {
    ErrorHandler errorHandler = getErrorHandler();
    if (errorHandler != null) {
      try {
        listener.onApplicationEvent(event);
      }
      catch (Throwable err) {
        errorHandler.handleError(err);
      }
    }
    else {
      listener.onApplicationEvent(event);
    }
  }

}
TOP

Related Classes of org.springframework.context.event.SimpleApplicationEventMulticaster

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.