这篇文章主要介绍了使用Spring事件机制实现异步的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
当把一个事件发布到Spring提供的ApplicationContext中,被监听器侦测到,就会执行对应的处理方法。
事件本身
事件是一个自定义的类,需要继承Spring提供的ApplicationEvent
。
?
1 2 3 4 5 6 7 8 9 |
@Data public class MyEvent extends ApplicationEvent { private String msg; public MyEvent(Object source, String msg) { super (source); this .msg = msg; } } |
事件监听
基本方法是实现ApplicationListener
接口,自定义一个监听器,实现onApplicationEvent()
方法,然后添加到ApplicationContext
。
比如:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public class MyListener implements ApplicationListener { @Override public void onApplicationEvent(MyEvent event) { System.out.print( "监听到MyEvent事件" ); } } ... // SpringBoot的启动类中添加监听器 public static void main(String[] args) { SpringApplication application = new SpringApplication(MyApplication. class ); application.addListeners( new MyListener()); application.run(args); } |
也可以使用注解@EventListener
(推荐):原理就是通过扫描这个注解,创建监听器并添加到ApplicationContext
。
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
@Component @Slf4j public class MyEventHandler { @EventListener public void handleEvent(MyEvent event) { log.info( "------------处理事件:{}" , event.getMsg()); try { Thread.sleep( 5 * 1000L); log.info( "事件1(5s)处理完成" ); } catch (InterruptedException e) { e.printStackTrace(); } } } |
事件发布
可以通过上下文对象的发布方法ConfigurableApplicationContext::publishEvent()
来发布。
也可以实现ApplicationEventPublisherAware
接口来发布(推荐)。
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
@Component @Slf4j public class EventService implements ApplicationEventPublisherAware { public ApplicationEventPublisher publisher; @Override public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { this .publisher = applicationEventPublisher; } public String doEventWork(String msg) { log.info( "------------publish event:" + msg); MyEvent event = new MyEvent( this , msg); publisher.publishEvent(event); return "OK" ; } } |
测试代码
?
1 2 3 4 5 6 7 8 9 10 11 12 |
@SpringBootTest @RunWith (SpringRunner. class ) public class EventServiceTest { @Autowired private EventService service; @Test public void eventTest() { String msg= "Java Code" ; service.doEventWork(msg); } } |
注意
如果2个事件之间是继承关系,会先监听到子类事件,处理完再监听父类。
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
// MyEvent2 extends MyEvent @Component @Slf4j public class MyEventHandler { @EventListener public void handleEvent(MyEvent event) { log.info( "------------处理事件:{}" , event.getMsg()); try { Thread.sleep( 5 * 1000L); log.info( "事件1(5s)处理完成" ); } catch (InterruptedException e) { e.printStackTrace(); } } @EventListener public void handleEvent2(MyEvent2 event) { log.info( "------------处理事件2:{}" , event.getMsg()); try { Thread.sleep( 10 * 1000L); log.info( "事件2(10s)处理完成" ); } catch (InterruptedException e) { e.printStackTrace(); } } } |
当我publish一个子类事件MyEvent2时,日志如下:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。