/**
 * Developer: Kadvin Date: 14-6-6 下午2:31
 */
package net.happyonroad.spring.support;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.SimpleApplicationEventMulticaster;
import org.springframework.context.event.SmartApplicationListener;

import java.util.HashSet;
import java.util.Set;

/**
 * 能够根据Listener的Event的Source Type进行过滤的派发器
 * <p/>
 * 另外，可以防止事件重复
 */
public class SmartApplicationEventMulticaster extends SimpleApplicationEventMulticaster {
    public SmartApplicationEventMulticaster(BeanFactory beanFactory) {
        super(beanFactory);
    }

    private Set<ApplicationEvent> events = new HashSet<ApplicationEvent>();

    protected boolean supportsEvent(ApplicationListener<?> listener,
                                    Class<? extends ApplicationEvent> eventType, Class<?> sourceType) {

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

    @Override
    public void multicastEvent(ApplicationEvent event) {
        //防止死循环导致的StackOverFlow, eg:
        // Platform Context --forwarder--> Spring Mvc Context
        // Spring Mvc Context -->multicast--> Parent Context(Platform Context)
        // ...
        if (remembered(event)) return;
        remember(event);
        super.multicastEvent(event);
    }


    private boolean remembered(ApplicationEvent event) {
        return events.contains(event);
    }

    private void remember(ApplicationEvent event) {
        events.add(event);
    }
}

@@ -416,16 +416,43 @@
 ashSet;%0A
+import java.util.Iterator;%0A
 import j
@@ -629,16 +629,125 @@
 aster %7B%0A
+    //%E6%9C%80%E5%A4%9A%E5%AD%98%E5%82%A85m%E5%86%85%E7%9A%84%E4%BA%8B%E4%BB%B6%EF%BC%8C5%E5%88%86%E9%92%9F%E5%89%8D%E7%9A%84%E4%BA%8B%E4%BB%B6%E5%B0%B1%E5%88%A0%E9%99%A4%0A    // %E9%81%BF%E5%85%8D%E8%BF%99%E9%87%8C%E5%86%85%E5%AD%98%E6%B3%84%E9%9C%B2%0A    private static final long MAX_STORAGE_TIME = 1000 * 60 * 5;%0A%0A
     publ
@@ -2014,32 +2014,383 @@
 nEvent event) %7B%0A
+        Iterator%3CApplicationEvent%3E it = events.iterator();%0A        //%E6%B2%A1%E6%9C%89%E4%B8%93%E9%97%A8%E9%85%8D%E7%BD%AE%E4%B8%80%E4%B8%AA%E5%AE%9A%E6%97%B6%E6%B8%85%E7%90%86%E7%9A%84%E4%BB%BB%E5%8A%A1%EF%BC%8C%E8%80%8C%E6%98%AF%E5%9C%A8%E6%9F%90%E6%AC%A1%E4%BA%8B%E4%BB%B6%E5%8F%91%E7%94%9F%E6%97%B6%E9%A1%BA%E5%B8%A6%E5%81%9A%E4%BA%8B%E4%BB%B6%E6%B8%85%E7%90%86%0A        while (it.hasNext()) %7B%0A            ApplicationEvent evt = it.next();%0A            long lives = System.currentTimeMillis() - evt.getTimestamp();%0A            if( lives %3E MAX_STORAGE_TIME )%7B%0A                it.remove();%0A            %7D%0A        %7D%0A
         events.a

Clear cached event in smart application event multicaster