- A+
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:
自定义事件
继承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);既成功发送。
@AutowiredApplicationContext 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种实现方式如下:
@Slf4jpublic 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
)