spring中的事件监听eventListener


title: spring中的事件监听eventListener
date: 2017-04-20 14:00:59
tags:
category: spring


spring基本内建event

spring内建的一些event 细节描述
ContextRefreshedEvent 从源码可知该事件在spring的上下文被初始化和刷新时触发。这里的刷新其实就是指由ConfigurableApplicationContext定义的refresh方法,在重新加载属性文件等时调用。
ContextStartedEvent spring上下文启动完成触发,既ConfigurableApplicationContext的start方法。奇怪的是spring自己启动完成后触发的不是这个事件,而是上面的RefreshedEvent。
ContextStoppedEvent ConfigurableApplicationContext.stop(),stop后的上下文是可以调用start再次启用的。
ContextClosedEvent ConfigurableApplicationContext.close() close方法后,所有bean被摧毁,无法再次start or refresh。
RequestHandledEvent web环境事件,在处理"完成"一个http request后,触发此事件

官网说明:http://docs.spring.io/spring/docs/2.5.x/reference/beans.html#context-functionality-events

springboot新加入一些内建event:

https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#boot-features-application-events-and-listeners

自定义事件

继承ApplicationEvent或相应子类。

4.2版本之后,不再强制要求继承ApplicationEvent,非ApplicationEvent子类的对象将被包装成PayloadApplicationEvent,其源码中的payload既我们传入的事件对象。

public class MyEvent<T> extends ApplicationContextEvent{
    private T data;
    /**
     * Create a new ContextStartedEvent.
     *
     * @param source the {@code ApplicationContext} that the event is raised for
     *               (must not be {@code null})
     */
    public MyEvent(ApplicationContext source) {
        super(source);
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}

如何发送事件

事件的发送者是实现了ApplicationEventPublisher接口的类。在spring中,其实就是你的ApplicationContext。

当你的bean实现ApplicationEventPublisherAware接口时,spring会自动为你注入ApplicationEventPublisher,也就是当前ApplicationContext。其实为了避免繁琐,直接注入即可。

调用applicationContext.publish(yourEvent);既成功发送。

@Autowired
ApplicationContext applicationContext;

public void send(){
    MyEvent myEvent = new MyEvent(applicationContext);
    myEvent.setData("some info,haha");
    applicationContext.publishEvent(myEvent);
}

事件监听器

同理事件的监听器,或者说处理者,既spring管理的bean中实现了ApplicationListener的相应类。根据事件的类型和对应listener接受的事件类型参数 ,被发送到相应的listener。

在spring4.2版中,允许在任一bean的对应方法上注解@EventListener来标记该bean实现了listener方法。实现更大程度的解耦。2种实现方式如下:

@Slf4j
public class MyEventListener implements ApplicationListener<MyEvent>{
    @Override
    public void onApplicationEvent(MyEvent event) {
        log.info("from MyEventListener :" + event);
        log.info("event type: "+event.getClass());
    }
    @EventListener
    public void someMethod(ApplicationEvent event) {
        log.info("event :"+event);
    }
}

这里有个进阶使用方式是如果@EventListener标记的方法的返回值不是void,返回的对象将再次作为一个Event被发送。

同时@EventListener也可以和@Async配合使用,使此方法被包裹成任务放入线程池中异步执行。(前提是开启了异步任务池设置@EnableAsync)

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,898评论 19 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 47,126评论 6 342
  • spring官方文档:http://docs.spring.io/spring/docs/current/spri...
    牛马风情阅读 5,726评论 0 3
  • 什么是Spring Spring是一个开源的Java EE开发框架。Spring框架的核心功能可以应用在任何Jav...
    jemmm阅读 16,697评论 1 133
  • 有一种丧心病狂就是认为自己弱爆了,我的那点好强的心啊,真的也是,一边安慰自己才两个月三等奖不错了,一边告诉自己这完...
    静守时光mxx阅读 1,801评论 0 0

友情链接更多精彩内容