事件监听

package com.example.observer.customization.event;

import java.util.EventObject;

/**
 * 事件的抽象
 */
public abstract class AppEvent extends EventObject {
    /**
     * Constructs a prototypical Event.
     *
     * @param source The object on which the Event initially occurred.
     * @throws IllegalArgumentException if source is null.
     */
    public AppEvent(Object source) {
        super(source);
    }
}
package com.example.observer.customization.listener;

import com.example.observer.customization.event.AppEvent;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.EventListener;

/**
 * 应用事件监听器接口
 */
public interface AppListener<E extends AppEvent> extends EventListener {

    void onAppEvent(E event);

    default boolean supportEventType(Class eventType){
        Type[] genericInterfaces = this.getClass().getGenericInterfaces();
        if (genericInterfaces.getClass().isAssignableFrom(ParameterizedType[].class)) {
            for (Type genericInterface : genericInterfaces) {
                ParameterizedType parameterizedType = (ParameterizedType) genericInterface;
                Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
                Type type = actualTypeArguments[0];
                if (type instanceof Class) {
                    Class clazz = (Class) type;
                    return clazz==eventType;
                }
            }
        }
        return false;
    }

    default boolean supportSourceType(Class sourceType) {
        return true;
    }
}
package com.example.observer.customization.multicaster;

import com.example.observer.customization.event.AppEvent;
import com.example.observer.customization.listener.AppListener;

/**
 * 事件广播器
 */
public interface AppEventMulticaster {

    /**
     * 添加监听器
     * @param listener
     */
    void addAppListener(AppListener<?> listener);

    /**
     * 广播事件给对应的监听器
     * @param event
     */
    void multicasterEvent(AppEvent event);
}
package com.example.observer.customization.multicaster;

import com.example.observer.customization.event.AppEvent;
import com.example.observer.customization.listener.AppListener;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public abstract class AbstractAppEventMulticaster implements AppEventMulticaster {

    private final ListenerHelper defaultHelper = new ListenerHelper();

    protected final Map<ListenerCacheKey,ListenerHelper> helperCache = new ConcurrentHashMap(64);

    @Override
    public void addAppListener(AppListener<?> listener) {
        defaultHelper.appListeners.add(listener);
    }


    /**
     * 根据事件返回对应的监听器集合
     * @param event
     * @return
     */
    protected Collection<AppListener<?>>  getAppListeners(AppEvent event){
        Object source = event.getSource();
        Class sourceType = source==null? null:source.getClass();
        ListenerCacheKey cacheKey = new ListenerCacheKey(event.getClass(),sourceType);
        ListenerHelper helper = helperCache.get(cacheKey);
        if (helper!=null) {
            return helper.getAppListeners();
        }else {
            // search defaultHelper
            helper = new ListenerHelper();
            Collection<AppListener<?>> listeners = getAppListeners(event.getClass(),sourceType,helper);
            helperCache.put(cacheKey,helper);
            return listeners;
        }
    }

    /**
     * 根据 eventType sourceType 从 defaultHelper中找到对应的listener集合,填充给helper并且返回
     * @param eventType
     * @param sourceType
     * @param helper
     * @return
     */
    private Collection<AppListener<?>> getAppListeners(Class eventType, Class sourceType, ListenerHelper helper) {
        Collection<AppListener<? extends AppEvent>> allListeners = defaultHelper.getAppListeners();
        List<AppListener<?>> returns = new ArrayList<>();
        for (AppListener<?> listener : allListeners) {
            if(supportEvent(listener,eventType,sourceType)) {
                if (helper!=null) {
                    helper.appListeners.add(listener);
                }
                returns.add(listener);
            }
        }
        return returns;
    }

    private boolean supportEvent(AppListener<?> listener, Class eventType, Class sourceType) {
        return listener.supportEventType(eventType) && listener.supportSourceType(sourceType);
    }


    private class ListenerCacheKey {

        private final Class eventType;
        private final Class sourceType;

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

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            ListenerCacheKey cacheKey = (ListenerCacheKey) o;
            return Objects.equals(eventType, cacheKey.eventType) && Objects.equals(sourceType, cacheKey.sourceType);
        }

        @Override
        public int hashCode() {
            return Objects.hash(eventType, sourceType);
        }

        @Override
        public String toString() {
            return "ListenerCacheKey{" +
                    "eventType=" + eventType +
                    ", sourceType=" + sourceType +
                    '}';
        }
    }


   private class ListenerHelper {

        private final Set<AppListener<? extends AppEvent>> appListeners = new LinkedHashSet<>();


        public Collection<AppListener<? extends AppEvent>> getAppListeners() {
            List<AppListener<? extends AppEvent>> allListeners  = new ArrayList<>(appListeners.size());
            allListeners.addAll(appListeners);
            return allListeners;
        }

   }



}
package com.example.observer.customization.multicaster;

import com.example.observer.customization.event.AppEvent;
import com.example.observer.customization.listener.AppListener;

import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class SimpleAppEventMulticaster extends AbstractAppEventMulticaster{

    private Executor executor = new ThreadPoolExecutor(
            5,
            10,
            60,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(100)
    );

    @Override
    public void multicasterEvent(AppEvent event) {
        // 1,找到对该事件感兴趣的监听器, 2,依次回调
        for (AppListener listener : getAppListeners(event)) {
            if (executor!=null) {
                executor.execute(()->{
                    invokeListener(listener,event);
                });
            }else {
                invokeListener(listener,event);
            }
        }
    }

    private void invokeListener(AppListener listener, AppEvent event) {
        try {
            listener.onAppEvent(event);
        } catch (Exception e) {
            e.printStackTrace();
            //////////.........不同的异常处理机制
        }
    }
}
package com.example.observer.customization.publisher;

import com.example.observer.customization.event.AppEvent;

public interface AppEventPublisher {

    void publishEvent(AppEvent event);

}
package com.example.observer.customization.publisher;

import com.example.observer.customization.event.AppEvent;
import com.example.observer.customization.multicaster.AppEventMulticaster;

public class DefaultAppEventPublisher implements AppEventPublisher{

    private AppEventMulticaster appEventMulticaster;

    public void setAppEventMulticaster (AppEventMulticaster appEventMulticaster) {
        this.appEventMulticaster = appEventMulticaster;
    }


    @Override
    public void publishEvent(AppEvent event) {
        appEventMulticaster.multicasterEvent(event);
    }
}

=======================================

package com.example.observer.event;

import com.example.observer.customization.event.AppEvent;

public class ConfigAddEvent extends AppEvent {
    private Integer id;
    /**
     * Constructs a prototypical Event.
     *
     * @param source The object on which the Event initially occurred.
     * @throws IllegalArgumentException if source is null.
     */
    public ConfigAddEvent(Object source,Integer id) {
        super(source);
        this.id = id;
    }
}
package com.example.observer.event;

import com.example.observer.customization.event.AppEvent;

public class ConfigDeleteEvent extends AppEvent {
    /**
     * Constructs a prototypical Event.
     *
     * @param source The object on which the Event initially occurred.
     * @throws IllegalArgumentException if source is null.
     */
    public ConfigDeleteEvent(Object source) {
        super(source);
    }
}
package com.example.observer.listener;

import com.example.observer.customization.listener.AppListener;
import com.example.observer.event.ConfigAddEvent;


public class ConfigAddListener implements AppListener<ConfigAddEvent> {
    @Override
    public void onAppEvent(ConfigAddEvent event) {
        System.out.println("ConfigAddListener----" + Thread.currentThread().getName() + ",event=" + event);
    }
}
package com.example.observer.listener;

import com.example.observer.customization.listener.AppListener;
import com.example.observer.event.ConfigAddEvent;


public class ConfigAddListener2 implements AppListener<ConfigAddEvent> {
    @Override
    public void onAppEvent(ConfigAddEvent event) {
        System.out.println("ConfigAddListener2----" + Thread.currentThread().getName() + ",event=" + event);
    }
}
package com.example.observer.listener;

import com.example.observer.customization.listener.AppListener;
import com.example.observer.event.ConfigDeleteEvent;

public class ConfigDeleteListener implements AppListener<ConfigDeleteEvent> {

    @Override
    public void onAppEvent(ConfigDeleteEvent event) {
        System.out.println("ConfigDeleteListener---" + Thread.currentThread().getName() + ",event=" + event);
    }
}
package com.example.observer;

import com.example.observer.customization.multicaster.AppEventMulticaster;
import com.example.observer.customization.multicaster.SimpleAppEventMulticaster;
import com.example.observer.customization.publisher.DefaultAppEventPublisher;
import com.example.observer.entity.Config;
import com.example.observer.event.ConfigAddEvent;
import com.example.observer.event.ConfigDeleteEvent;
import com.example.observer.listener.ConfigAddListener;
import com.example.observer.listener.ConfigAddListener2;
import com.example.observer.listener.ConfigDeleteListener;

public class ObserverTest {

    public static void main(String[] args) {
        // multicaster
        AppEventMulticaster multicaster = new SimpleAppEventMulticaster();
        //add listener
        multicaster.addAppListener(new ConfigAddListener());
        multicaster.addAppListener(new ConfigAddListener2());
        multicaster.addAppListener(new ConfigDeleteListener());

        // publisher
        DefaultAppEventPublisher publisher = new DefaultAppEventPublisher();
        publisher.setAppEventMulticaster(multicaster);



        // publish event
        publisher.publishEvent(new ConfigAddEvent(new Config(12,"g1","n1","add1"),12));
        System.out.println("业务继续执行");
        publisher.publishEvent(new ConfigDeleteEvent(new Config(13,"g1","n1","del13")));
        System.out.println("finish");
    }
}

 

posted @ 2024-04-01 22:59  yydssc  阅读(16)  评论(0)    收藏  举报