上篇文章我们看到SpringBoot应用在启动时提供了几种事件的监听,今天来看下如何自定义一个监听器。
日常项目中,很多业务场景会用到监听器,比如在Service中处理业务时,我们需要记录一个操作的日志到数据库中,我们怎么实现呢?
分析场景
1.我们需要一个Service类来处理业务。
2.在操作完或者报错的时候,要监听到事件并处理,所以需要一个监听类和一个事件类。
一、新建实体类
实体类用来进行业务操作对象的映射。
packagecom.xing.studyboot.entity.dto; importlombok.Data; /*** 业务日志记录实体类* @author xing**/publicclassBusinessLogDto { /*** 业务类型*/privateStringtype; /*** 业务处理时长*/privatelongbusinessTime; /*** 业务处理结果*/privateStringresult; /*** 请求参数*/privateStringparams; /*** 操作者*/publicStringreceiver; }
二、建一个事件,集成ApplicationEvent类
packagecom.xing.studyboot.event; importorg.springframework.context.ApplicationEvent; importcom.xing.studyboot.entity.dto.BusinessLogDto; importlombok.Getter; /*** 业务日志事件* @author xing**/publicclassBusinessLogEventextendsApplicationEvent { privatestaticfinallongserialVersionUID=1L; privateBusinessLogDtobusinessLogDto; publicBusinessLogEvent(Objectsource, BusinessLogDtobusinessLogDto) { super(source); this.businessLogDto=businessLogDto; } }
三、注册业务日志的监听器
这里注册有多种方法,我们使用@Component注解,实现 ApplicationListener<BusinessLogEvent> 接口。
packagecom.xing.studyboot.listener; importorg.springframework.context.ApplicationListener; importorg.springframework.core.annotation.Order; importorg.springframework.stereotype.Component; importcom.xing.studyboot.entity.dto.BusinessLogDto; importcom.xing.studyboot.event.BusinessLogEvent; /*** 注册业务日志的监听器* @author xing* @createTime*/1) (publicclassBusinessLogListenerimplementsApplicationListener<BusinessLogEvent> { publicvoidonApplicationEvent(BusinessLogEventbusinessLogEvent) { BusinessLogDtobusinessLogDto=businessLogEvent.getBusinessLogDto(); System.out.println("BusinessLogListener接收到的监听数据是->"+businessLogDto); } }
四、在业务类中将事件发布到应用
packagecom.xing.studyboot.rest.service.impl; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.context.ApplicationContext; importorg.springframework.stereotype.Service; importcom.xing.studyboot.entity.dto.BusinessLogDto; importcom.xing.studyboot.event.BusinessLogEvent; importcom.xing.studyboot.rest.service.CommonService; publicclassCommonServiceImplimplementsCommonService { privateApplicationContextapplicationContext; publicStringindex() { BusinessLogDtodto=newBusinessLogDto(); dto.setType("0"); dto.setResult("ok"); dto.setParams("params"); dto.setBusinessTime(20L); dto.setReceiver("xinghua"); System.out.println("CommonServiceImpl->记录操作日志,发布事件到应用"); applicationContext.publishEvent(newBusinessLogEvent(this, dto)); return"CommonServiceImpl.index"; } }
测试发现,输出了监听到的发布事件。
五、也可以用@EventListener注解来注册监听器,等同于上面的实现 ApplicationListener<BusinessLogEvent> 接口。
@Async是异步监听
packagecom.xing.studyboot.listener; importorg.springframework.context.event.EventListener; importorg.springframework.core.annotation.Order; importorg.springframework.scheduling.annotation.Async; importorg.springframework.stereotype.Component; importcom.xing.studyboot.entity.dto.BusinessLogDto; importcom.xing.studyboot.event.BusinessLogEvent; /*** 使用注解的形式注册监听器* @author xing* @createTime*/2) (publicclassBusinessLogAnnotationListener { /*** 注册监听实现方法* @param businessLogEvent 业务处理推送事件*/publicvoidregister(BusinessLogEventbusinessLogEvent) { // 获取业务处理日志对象BusinessLogDtobusinessLogDto=businessLogEvent.getBusinessLogDto(); System.out.println("BusinessLogAnnotationListener接收到的监听数据是->"+businessLogDto); } }
测试发现同样监听到了事件,ok!
@Order(2)注解可以设置监听器的优先级。