1. 程式人生 > >Spring原始碼之事件驅動模型

Spring原始碼之事件驅動模型

SpringContext中初始化事件釋出者 ###

//spring初始化事件的地方
//spring初始化事件的地方
public abstract class AbstractApplicationContext extends DefaultResourceLoader
        implements ConfigurableApplicationContext, DisposableBean {

    /** 用於事件釋出 */
    private ApplicationEventMulticaster applicationEventMulticaster;

    /** 靜態指定的監聽器*/
private Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<ApplicationListener<?>>(); //======省略一段程式碼========/ 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. * <p>如果在上下文中沒有定義,則使用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” <bean id="applicationEventMulticaster" class="org.springframework.context.event.SimpleApplicationEventMulticaster"> <!-- 注入任務執行器 這樣就實現了非同步呼叫(缺點是全域性的,要麼全部非同步,要麼全部同步(刪除這個屬性即是同步)) --> <property name="taskExecutor" ref="executor"/> </bean>

事件ApplicationEvent

//第一部分: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;
    }

}

目標(釋出事件者)ApplicationEventMulticaster (核心)


//第二部分:應用程式事件廣播介面
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<ListenerCacheKey, ListenerRetriever> retrieverCache =
            new ConcurrentHashMap<ListenerCacheKey, ListenerRetriever>(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<ApplicationListener> getApplicationListeners() {
        synchronized (this.defaultRetriever) {
            return this.defaultRetriever.getApplicationListeners();
        }
    }


     //返回與給定事件型別匹配的ApplicationListeners集合。 不匹配的聽眾早日被排除在外。
    protected Collection<ApplicationListener> 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<ApplicationListener> 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<ApplicationListener> retrieveApplicationListeners(
            Class<? extends ApplicationEvent> eventType, Class<?> sourceType, ListenerRetriever retriever) {

        LinkedList<ApplicationListener> allListeners = new LinkedList<ApplicationListener>();
        Set<ApplicationListener> listeners;
        Set<String> listenerBeans;
        synchronized (this.defaultRetriever) {
            listeners = new LinkedHashSet<ApplicationListener>(this.defaultRetriever.applicationListeners);
            listenerBeans = new LinkedHashSet<String>(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類封裝了一組特定的目標監聽器,可以有效地檢索預過濾的監聽器。
    //<p>每個事件型別和源型別都會快取此幫助器的一個例項。
    private class ListenerRetriever {
        //監聽者bean例項列表
        public final Set<ApplicationListener> applicationListeners;
        //監聽者bean名稱列表
        public final Set<String> applicationListenerBeans;
        //預過濾
        private final boolean preFiltered;

        public ListenerRetriever(boolean preFiltered) {
            this.applicationListeners = new LinkedHashSet<ApplicationListener>();
            this.applicationListenerBeans = new LinkedHashSet<String>();
            this.preFiltered = preFiltered;
        }
        //返回監聽者例項列表
        public Collection<ApplicationListener> getApplicationListeners() {
            LinkedList<ApplicationListener> allListeners = new LinkedList<ApplicationListener>();
            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);
            }
        }
    }

}

監聽器 EventListener

public interface EventListener {
}

public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {

    /**
     * 處理事件訊息的地方
     * @param event the event to respond to
     */
    void onApplicationEvent(E event);

}