Springソースのイベント駆動モデル

34734 ワード

Spring Conteetの初期化イベントの発布者22123;
//spring        
//spring        
public abstract class AbstractApplicationContext extends DefaultResourceLoader
        implements ConfigurableApplicationContext, DisposableBean {

    /**        */
    private ApplicationEventMulticaster applicationEventMulticaster;

    /**         */
    private Set> applicationListeners = new LinkedHashSet>();

    //======      ========/
    public void refresh() throws BeansException, IllegalStateException {

        //======      ========/
        // Initialize event multicaster for this context.
        initApplicationEventMulticaster();
        // Initialize other special beans in specific context subclasses.
        onRefresh();

        //      bean     。
        registerListeners();

        //======      ========/
    }

    //======      ========/

    /**
     *    ApplicationEventMulticaster.
     * 

, SimpleApplicationEventMulticaster。 * @see org.springframework.context.event.SimpleApplicationEventMulticaster */

protected void initApplicationEventMulticaster() { // bean ConfigurableListableBeanFactory beanFactory = getBeanFactory(); // ApplicationEventMulticaster ( ) if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) { this.applicationEventMulticaster = beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class); if (logger.isDebugEnabled()) { logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]"); } } else {// , , , this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster); if (logger.isDebugEnabled()) { logger.debug("Unable to locate ApplicationEventMulticaster with name '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "': using default [" + this.applicationEventMulticaster + "]"); } } } /** * ApplicationListener bean * Doesn't affect other listeners, which can be added without being beans. */ protected void registerListeners() { // 。 for (ApplicationListener> listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } /** * FactoryBeans: bean , bean ! */ // ApplicationListener //includeNonSingletons false Bean,true //allowEagerInit true ,false 。 String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String lisName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(lisName); } } // public void publishEvent(ApplicationEvent event) { Assert.notNull(event, "Event must not be null"); if (logger.isTraceEnabled()) { logger.trace("Publishing event in " + getDisplayName() + ": " + event); } // applicationEventMulticaster , multicastEvent(event) getApplicationEventMulticaster().multicastEvent(event); if (this.parent != null) { this.parent.publishEvent(event); } } } // , ,id “applicationEventMulticaster” "applicationEventMulticaster" class="org.springframework.context.event.SimpleApplicationEventMulticaster"> "taskExecutor" ref="executor"/>
イベントアプリイベント
//    :spring      
public class EventObject implements java.io.Serializable {

    private static final long serialVersionUID = 5516075349620653480L;

    /**
     *          。
     */
    protected transient Object  source;

    //    
    public EventObject(Object source) {
        if (source == null)
            throw new IllegalArgumentException("null source");

        this.source = source;
    }

    public Object getSource() {
        return source;
    }

    public String toString() {
        return getClass().getName() + "[source=" + source + "]";
    }
}
//   
public abstract class ApplicationEvent extends EventObject {

    /** use serialVersionUID from Spring 1.2 for interoperability */
    private static final long serialVersionUID = 7099057708183571937L;

    /** System time when the event happened */
    private final long timestamp;


    /**
     * Create a new ApplicationEvent.
     * @param source the component that published the event (never {@code null})
     */
    public ApplicationEvent(Object source) {
        super(source);
        this.timestamp = System.currentTimeMillis();
    }


    /**
     * Return the system time in milliseconds when the event happened.
     */
    public final long getTimestamp() {
        return this.timestamp;
    }

}
ターゲット(イベント投稿者)Application Event Multicaster(コア)

//    :          
public interface ApplicationEventMulticaster {

    /**
     *        bean
     * @param listener the listener to add
     */
    void addApplicationListener(ApplicationListener listener);

    /**
     *         beanName
     * @param listenerBeanName the name of the listener bean to add
     */
    void addApplicationListenerBean(String listenerBeanName);

    /**
     *        bean
     * @param listener the listener to remove
     */
    void removeApplicationListener(ApplicationListener listener);

    /**
     *        beanName
     * @param listenerBeanName the name of the listener bean to add
     */
    void removeApplicationListenerBean(String listenerBeanName);

    /**
     *        Multicaster      。
     */
    void removeAllListeners();

    /**
     *                    。
     * @param event the event to multicast
     */
    void multicastEvent(ApplicationEvent event);

}

//    
public interface Aware {

}

//      BeanFactory
public interface BeanFactoryAware extends Aware {

    void setBeanFactory(BeanFactory beanFactory) throws BeansException;

}
//      bean     
public interface BeanClassLoaderAware extends Aware {

    void setBeanClassLoader(ClassLoader classLoader);

}

//       ,           
public abstract class AbstractApplicationEventMulticaster
        implements ApplicationEventMulticaster, BeanClassLoaderAware, BeanFactoryAware {
    //   (    :          beanName)
    private final ListenerRetriever defaultRetriever = new ListenerRetriever(false);

    private final Map retrieverCache =
            new ConcurrentHashMap(64);
    //   :   null ,    eventType sourceType      ClassLoader      。
    private ClassLoader beanClassLoader;
    //bean  :    defaultRetriever listenerBeanName    bean  
    private BeanFactory beanFactory;

    //       bean
    public void addApplicationListener(ApplicationListener listener) {
        synchronized (this.defaultRetriever) {
            this.defaultRetriever.applicationListeners.add(listener);
            this.retrieverCache.clear();
        }
    }
    //       beanName
    public void addApplicationListenerBean(String listenerBeanName) {
        synchronized (this.defaultRetriever) {
            this.defaultRetriever.applicationListenerBeans.add(listenerBeanName);
            this.retrieverCache.clear();
        }
    }
    //       bean
    public void removeApplicationListener(ApplicationListener listener) {
        synchronized (this.defaultRetriever) {
            this.defaultRetriever.applicationListeners.remove(listener);
            this.retrieverCache.clear();
        }
    }
    //       beanName
    public void removeApplicationListenerBean(String listenerBeanName) {
        synchronized (this.defaultRetriever) {
            this.defaultRetriever.applicationListenerBeans.remove(listenerBeanName);
            this.retrieverCache.clear();
        }
    }
    //       
    public void removeAllListeners() {
        synchronized (this.defaultRetriever) {
            this.defaultRetriever.applicationListeners.clear();
            this.defaultRetriever.applicationListenerBeans.clear();
            this.retrieverCache.clear();
        }
    }

    public void setBeanClassLoader(ClassLoader classLoader) {
        this.beanClassLoader = classLoader;
    }

    public void setBeanFactory(BeanFactory beanFactory) {
        this.beanFactory = beanFactory;
        if (this.beanClassLoader == null && beanFactory instanceof ConfigurableBeanFactory) {
            this.beanClassLoader = ((ConfigurableBeanFactory) beanFactory).getBeanClassLoader();
        }
    }

    private BeanFactory getBeanFactory() {
        if (this.beanFactory == null) {
            throw new IllegalStateException("ApplicationEventMulticaster cannot retrieve listener beans " +
                    "because it is not associated with a BeanFactory");
        }
        return this.beanFactory;
    }


    //           
    protected Collection getApplicationListeners() {
        synchronized (this.defaultRetriever) {
            return this.defaultRetriever.getApplicationListeners();
        }
    }


     //            ApplicationListeners  。              。
    protected Collection getApplicationListeners(ApplicationEvent event) {
        Class extends ApplicationEvent> eventType = event.getClass();
        Object source = event.getSource();
        Class> sourceType = (source != null ? source.getClass() : null);
        ListenerCacheKey cacheKey = new ListenerCacheKey(eventType, sourceType);

        //     
        ListenerRetriever retriever = this.retrieverCache.get(cacheKey);
        if (retriever != null) {
            return retriever.getApplicationListeners();
        }
        //     
        if (this.beanClassLoader == null ||
                //        ,              ,       ClassLoader      。
                (ClassUtils.isCacheSafe(eventType, this.beanClassLoader) &&
                        (sourceType == null || ClassUtils.isCacheSafe(sourceType, this.beanClassLoader)))) {
            // Fully synchronized building and caching of a ListenerRetriever
            synchronized (this.defaultRetriever) {
                retriever = this.retrieverCache.get(cacheKey);
                if (retriever != null) {
                    return retriever.getApplicationListeners();
                }
                retriever = new ListenerRetriever(true);
                Collection listeners = retrieveApplicationListeners(eventType, sourceType, retriever);
                //    
                this.retrieverCache.put(cacheKey, retriever);
                return listeners;
            }
        }
        else {
            //  ListenerRetriever   - >   synchronization
            return retrieveApplicationListeners(eventType, sourceType, null);
        }
    }

    /**
     *                       。
     * @param eventType the application event type
     * @param sourceType the event source type
     * @param retriever the ListenerRetriever, if supposed to populate one (for caching purposes)
     * @return the pre-filtered list of application listeners for the given event and source type
     */
    private Collection retrieveApplicationListeners(
            Class extends ApplicationEvent> eventType, Class> sourceType, ListenerRetriever retriever) {

        LinkedList allListeners = new LinkedList();
        Set listeners;
        Set listenerBeans;
        synchronized (this.defaultRetriever) {
            listeners = new LinkedHashSet(this.defaultRetriever.applicationListeners);
            listenerBeans = new LinkedHashSet(this.defaultRetriever.applicationListenerBeans);
        }
        for (ApplicationListener listener : listeners) {
            if (supportsEvent(listener, eventType, sourceType)) {
                if (retriever != null) {
                    retriever.applicationListeners.add(listener);
                }
                allListeners.add(listener);
            }
        }
        if (!listenerBeans.isEmpty()) {
            BeanFactory beanFactory = getBeanFactory();
            for (String listenerBeanName : listenerBeans) {
                ApplicationListener listener = beanFactory.getBean(listenerBeanName, ApplicationListener.class);
                if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
                    if (retriever != null) {
                        retriever.applicationListenerBeans.add(listenerBeanName);
                    }
                    allListeners.add(listener);
                }
            }
        }
        OrderComparator.sort(allListeners);
        return allListeners;
    }

    //                 。
    protected boolean supportsEvent(
            ApplicationListener listener, Class extends ApplicationEvent> eventType, Class> sourceType) {

        SmartApplicationListener smartListener = (listener instanceof SmartApplicationListener ?
                (SmartApplicationListener) listener : new GenericApplicationListenerAdapter(listener));
        return (smartListener.supportsEventType(eventType) && smartListener.supportsSourceType(sourceType));
    }


    /**
     * Cache key for ListenerRetrievers, based on event type and source type.
     *            ListenerRetrievers   。
     */
    private static class ListenerCacheKey {
        //    
        private final Class> eventType;
        //source  
        private final Class> sourceType;

        public ListenerCacheKey(Class> eventType, Class> sourceType) {
            this.eventType = eventType;
            this.sourceType = sourceType;
        }

        @Override
        public boolean equals(Object other) {
            if (this == other) {
                return true;
            }
            ListenerCacheKey otherKey = (ListenerCacheKey) other;
            return ObjectUtils.nullSafeEquals(this.eventType, otherKey.eventType) &&
                    ObjectUtils.nullSafeEquals(this.sourceType, otherKey.sourceType);
        }

        @Override
        public int hashCode() {
            return ObjectUtils.nullSafeHashCode(this.eventType) * 29 + ObjectUtils.nullSafeHashCode(this.sourceType);
        }
    }


    //Helper              ,              。
    //

private class ListenerRetriever { // bean public final Set applicationListeners; // bean public final Set applicationListenerBeans; // private final boolean preFiltered; public ListenerRetriever(boolean preFiltered) { this.applicationListeners = new LinkedHashSet(); this.applicationListenerBeans = new LinkedHashSet(); this.preFiltered = preFiltered; } // public Collection getApplicationListeners() { LinkedList allListeners = new LinkedList(); for (ApplicationListener listener : this.applicationListeners) { allListeners.add(listener); } if (!this.applicationListenerBeans.isEmpty()) { // bean BeanFactory beanFactory = getBeanFactory(); for (String listenerBeanName : this.applicationListenerBeans) { // bean ( ) ApplicationListener listener = beanFactory.getBean(listenerBeanName, ApplicationListener.class); // ( ) allListeners ; , if (this.preFiltered || !allListeners.contains(listener)) { allListeners.add(listener); } } } // OrderComparator.sort(allListeners); return allListeners; } } } //spring public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster { // private Executor taskExecutor; // public SimpleApplicationEventMulticaster() { } /** * Create a new SimpleApplicationEventMulticaster for the given BeanFactory. */ public SimpleApplicationEventMulticaster(BeanFactory beanFactory) { setBeanFactory(beanFactory); } // Executor 。 public void setTaskExecutor(Executor taskExecutor) { this.taskExecutor = taskExecutor; } protected Executor getTaskExecutor() { return this.taskExecutor; } @SuppressWarnings("unchecked") public void multicastEvent(final ApplicationEvent event) { for (final ApplicationListener listener : getApplicationListeners(event)) { Executor executor = getTaskExecutor(); // ( , Executor ) if (executor != null) { executor.execute(new Runnable() { public void run() { listener.onApplicationEvent(event); } }); } else {// ( : ) listener.onApplicationEvent(event); } } } }
モニターEvent Listener
public interface EventListener {
}

public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {

    /**
     *          
     * @param event the event to respond to
     */
    void onApplicationEvent(E event);

}