当前位置: 首页 > 科技观察

SpringApplicationEvent事件实现本地事件驱动

时间:2023-03-13 16:05:31 科技观察

一、介绍Spring内置了一个简单的事件机制,可以很方便的实现事件驱动。核心类包括ApplicationEvent、具体的事件内容、事件抽象基类,可以继承该类来自定义具体的事件。EventApplicationEventPublisher,事件发布者,可以发布ApplicationEvent,也可以发布普通Object对象ApplicationListener,事件监听器,可以使用注解@EventListenerTransactionalEventListener,事务事件监听器,可以监听事务提交前,提交后,事务回滚,事务完成(成功或failure)2.使用示例:不定义事件,直接发布Object对象,同步1.定义发送事件的对象publicclassUserEntity{privatelongid;私有字符串名称;privateStringmsg;}2.定义事件监听器可以添加Condition条件,限制监听特定事件@Slf4j@ComponentpublicclassRegisterListener{@EventListener(condition="#entity.id!=nulland#entity.async==false")publicvoidhandlerEvent(UserEntityentity){try{//休眠5秒TimeUnit.SECONDS.sleep(5);}catch(InterruptedExceptione){e.printStackTrace();}log.info("handlerEvent:{}",entity);}}3.定义发送接口和实现类publicinterfaceIRegisterService{publicvoidregister(Stringname);}@ServicepublicclassRegisterServiceImpl实现IRegisterService{@ResourceprivateApplicationEventPublisherapplicationEventPublisher;@Overridepublicvoidregister(Stringname){UserEntityentity=newUserEntity();entity.setName(名字);实体.setId(1L);entity.setMsg("新用户注册同步调用");applicationEventPublisher.publishEvent(实体);}}4.测试Controller类进行测试@Slf4j@ControllerpublicclassTestController{@ResourceprivateIRegisterServiceregisterService;@RequestMapping("test")@ResponseBodypublicvoidtest1(Stringname){registerService.register(name);log.info("执行同步调用结束");}}在浏览器中输入地址:http://localhost/test?name=nik控制台输出:handlerEvent:UserEntity(id=1,name=nik,msg=newuserregistrationsynchronouscall)Executesynchronouscallend3.用法示例:异步发布1.在启动类中添加异步注解@EnableAsync2.在监听方法中添加注解@Async@Async@EventListener(condition="#entity.name!=nulland#entity.async")publicvoidhandlerEventAsync(用户实体实体){尝试{TimeUnit.SECONDS。睡觉(5);}catch(InterruptedExceptione){e.printStackTrace();}log.info("handlerEventAsync:{}",entity);}3.向服务添加异步发送方法@OverridepublicvoidregisterAsyn(Stringname){UserEntityentity=newUserEntity();entity.setName(名字);实体.setId(1L);entity.setMsg("新用户注册异步调用");entity.setAsync(true);applicationEventPublisher.publishEvent(entity);}3.测试@RequestMapping("test")@ResponseBodypublicvoidtest(Stringname){registerService.registerAsyn(name);log.info("异步调用执行结束");}控制台输出:异步调用执行结束handlerEventAsync:UserEntity(id=1,name=nik,msg=newuserregistrationasynchronouscall)4.使用示例:Publish交易提交后的事件只有提交成功后才表示成功Spring提供注解@TransactionalEventListener来监听事务事件。在@EventListener的基础上,增加了属性phase,包括以下四个值:AFTER_COMMIT,事务提交成功后,默认为BEFORE_COMMIT,AFTER_ROLLBACK,事务提交前,AFTER_COMPLETION,事务回滚后,事务完成后,AFTER_COMMIT或AFTER_ROLLBACK1,自定义事务处理事件publicclassRegisterCommitEventextendsApplicationEvent{@Getter@SetterprivateStringmsg;@Getter@Setter私有字符串名称;publicRegisterCommitEvent(UserEntitysource){super(source);this.msg=source.getMsg();this.name=source.getName();}}2.在处理方法上添加事务注解,@Transactional@Override@TransactionalpublicvoidregisterCommit(Stringname){UserEntityentity=newUserEntity();entity.setName(名称);entity.setMsg("新用户注册交易提交事件");RegisterCommitEventregisterEvent=newRegisterCommitEvent(实体);userDao.save(实体);//发送事件applicationEventPublisher.publishEvent(registerEvent);}3.添加交易事件Listen@Async@TransactionalEventListener(phase=TransactionPhase.AFTER_COMMIT)publicvoidhandlerEventCmmit(RegisterCommitEvent事件){尝试{TimeUnit.SECONDS.sleep(5);}catch(InterruptedExceptione){e.printStackTrace();}log.info("handlerEventCmmit:{}",event);}4.Test@RequestMapping("test")@ResponseBodypublicvoidtest(Stringname){registerService.registerCommit(name);log.info("Endofexecutioningtransactioncall");}Consoleoutput:EndofexecutingtransactioncallhandlerEventCmmit:RegisterCommitEvent[source=UserEntity(id=0,name=nik,msg=newuserregistrationtransactionsubmissionevent)]总结SpringApplicationEvent事件处理机制使用简单方便,可以有效解耦程序。虽然可以发送任何类型的对象,但在实际业务中很容易造成混淆。建议根据实际业务定义各种事件,在监听方法中实现异步处理。