ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

简单实现下监听

2022-04-12 14:35:30  阅读:177  来源: 互联网

标签:userName eventListeners 实现 监听 listener 事件 监听器 简单 public


监听器提供了一种获取服务器运行状况、动态干预的方式,服务器在运行期间发生指定变化时及时介入干预。

 

首先我们定义一个监听事件的抽象类,所有事件都需要继承该类

 1 public abstract class AbstractEvent {
 2     //事件源
 3     protected Object source;
 4 
 5     public AbstractEvent(Object source) {
 6         this.source = source;
 7     }
 8 
 9     public Object getSource() {
10         return source;
11     }
12 
13     public void setSource(Object source) {
14         this.source = source;
15     }
16 
17 }

 

我们使用一个接口来表示事件监听器,是个泛型接口,后面的类型E表示当前监听器需要监听的事件类型,此接口中只有一个方法,用来实现处理事件的业务;其定义的监听器需要实现这个接口。

/**
 * 事件监听器
 *
 * @param <E> 当前监听器感兴趣的事件类型
 */
public interface  EventListener  <E extends AbstractEvent>{
    /**
     * 此方法负责处理事件
     *
     * @param event 要响应的事件对象
     */
    void onEvent(E event);

}

 

事件广播器

  • 讲白了就是在spring加载的时候去获取所有的EventListener 
/**
 * 事件广播器:
 * 1.负责事件监听器的管理(注册监听器&移除监听器,将事件和监听器关联起来)
 * 2.负责事件的广播(将事件广播给所有的监听器,对该事件感兴趣的监听器会处理该事件)
 */
public interface EventMulticaster {
    /**
     * 广播事件给所有的监听器,对该事件感兴趣的监听器会处理该事件
     *
     * @param event
     */
    void multicastEvent(AbstractEvent event);

    /**
     * 添加一个事件监听器(监听器中包含了监听器中能够处理的事件)
     *
     * @param listener 需要添加监听器
     */
    void addEventListener(EventListener<?> listener);


    /**
     * 将事件监听器移除
     *
     * @param listener 需要移除的监听器
     */
    void removeEventListener(EventListener<?> listener);
}

 

到这里为止,一个简单的监听器的框架已经大致搭建完成了,下面我们看下他的简单的实现

 

首先是对于AbstractEvent,我们需要定义一个具体的事件,基于这个是事件去完成我们的监听

public class UserRegisterSuccessEvent extends AbstractEvent {
    //用户名
    private String userName;

    /**
     * 创建用户注册成功事件对象
     *
     * @param source   事件源
     * @param userName 当前注册的用户名
     */
    public UserRegisterSuccessEvent(Object source, String userName) {
        super(source);
        this.userName = userName;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;

    }
}

其次,对于监听器我们需要在事件触发的时候具体的去执行我们的实现,并且我们需要监听器在spring中被具体的感知,所以需要添加注解@Component

@Component
public class SendEmailOnUserRegisterSuccessListener implements EventListener<UserRegisterSuccessEvent>{
    @Override
    public void onEvent(UserRegisterSuccessEvent event) {
        System.out.println(
                String.format("给用户【%s】发送注册成功邮件!", event.getUserName()));
    }
}

 

然后,我们完成广播器的实现,把监听器放到容器中

/**
 * 事件广播器简单实现
 */
public class SimpleEventMulticaster implements EventMulticaster{
    private Map<Class<?>, List<EventListener>> eventObjectEventListenerMap = new ConcurrentHashMap<>();

    @Override
    public void multicastEvent(AbstractEvent event) {
        List<EventListener> eventListeners = this.eventObjectEventListenerMap.get(event.getClass());
        if (eventListeners != null) {
            for (EventListener eventListener : eventListeners) {
                eventListener.onEvent(event);
            }
        }
    }

    @Override
    public void addEventListener(EventListener<?> listener) {
        Class<?> eventType = this.getEventType(listener);
        List<EventListener> eventListeners = this.eventObjectEventListenerMap.get(eventType);
        if (eventListeners == null) {
            eventListeners = new ArrayList<>();
            this.eventObjectEventListenerMap.put(eventType, eventListeners);
        }
        eventListeners.add(listener);
    }

    @Override
    public void removeEventListener(EventListener<?> listener) {
        Class<?> eventType = this.getEventType(listener);
        List<EventListener> eventListeners = this.eventObjectEventListenerMap.get(eventType);
        if (eventListeners != null) {
            eventListeners.remove(listener);
        }

    }

    /**
     * 获取事件监听器需要监听的事件类型
     *
     * @param listener
     * @return
     */
    protected Class<?> getEventType(EventListener listener) {
        ParameterizedType parameterizedType = (ParameterizedType) listener.getClass().getGenericInterfaces()[0];
        Type eventType = parameterizedType.getActualTypeArguments()[0];
        return (Class<?>) eventType;
    }

}

接下来是最重要的,我们通过配置把获取监听器的List,把他放到容器里面,然后我们具体的服务可以去获取到这个容器从而进行广播,当事件发生的时候去触发具体的操作

public class ListenConfig {
    //这里是测试代码 这个bean会实列化两次,所以最好能在外面返回
    static EventMulticaster eventPublisher = new SimpleEventMulticaster();

    /**
     * 注册一个bean:事件发布者
     *
     * @param eventListeners
     * @return
     */
    @Bean
    public EventMulticaster eventMulticaster(List<EventListener> eventListeners) { //@1

        if (eventListeners != null) {
            eventListeners.forEach(eventPublisher::addEventListener);
        }
        return eventPublisher;
    }

    /**
     * 注册一个bean:用户注册服务
     *
     * @param eventMulticaster
     * @return
     */
    @Bean
    public UserRegisterService userRegisterService(EventMulticaster eventMulticaster) { //@2
        UserRegisterService userRegisterService = new UserRegisterService();
        userRegisterService.setEventMulticaster(eventMulticaster);
        return userRegisterService;
    }

}

业务代码

public class UserRegisterService {

    //事件发布者
    private EventMulticaster eventMulticaster; //@0

    /**
     * 注册用户
     *
     * @param userName 用户名
     */
    public void registerUser(String userName) { //@1
        //用户注册(将用户信息入库等操作)
        System.out.println(String.format("用户【%s】注册成功", userName)); //@2
        //广播事件
        UserRegisterSuccessEvent userRegisterSuccessEvent = new UserRegisterSuccessEvent(this, userName);
        this.eventMulticaster.multicastEvent(userRegisterSuccessEvent); //@3
    }

    public EventMulticaster getEventMulticaster() {
        return eventMulticaster;
    }

    public void setEventMulticaster(EventMulticaster eventMulticaster) {
        this.eventMulticaster = eventMulticaster;
    }
}

执行结果

2022-04-12 11:35:59.294  INFO 21068 --- [           main] c.example.listen.ListenApplicationTests  : Started ListenApplicationTests in 2.975 seconds (JVM running for 3.862)
用户【bosssoft小王】注册成功
给用户【bosssoft小王】发送注册成功邮件!
Disconnected from the target VM, address: '127.0.0.1:50071', transport: 'socket'

 

标签:userName,eventListeners,实现,监听,listener,事件,监听器,简单,public
来源: https://www.cnblogs.com/cowardy/p/16134939.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有