springevent是spring的一个基于观察者模式的事件消费框架,可以轻松的实现业务解耦,比如发送邮件,短信,记录日志,或其他与主业务没有强相关的逻辑处理,从而提高接口的响应速度,解耦业务逻辑,使这些操作不影响主业务逻辑的执行。
实现方式很简单
1.定义事件模型 通过继承ApplicationEvent ,其中的属性可以自定义,一般为此事件需要接收的参数。
ublic class AsyncAddWatermarkEvent extends ApplicationEvent {
BpiFileInfo bpiFileInfo;
public BpiFileInfo getBpiFileInfo() {
return bpiFileInfo;
}
public AsyncAddWatermarkEvent(Object source) {
super(source);
this.bpiFileInfo = (BpiFileInfo) source;
}
}
2.定义事件监听器和处理器,当监听到事件发布,便处理此事件,我此处以文件上传后,word文档转pdf文件并加水印为例。
@Slf4j
@Component
public class AsyncSendEmailEventHandler implements ApplicationListener<AsyncAddWatermarkEvent> {
@Resource
BpiFileInfoMapper bpiFileInfoMapper;
/**
* Handle an application event.
*
* @param event the event to respond to
*/
@Async("taskExecutor")
@Override
public void onApplicationEvent(AsyncAddWatermarkEvent event) {
log.info("给发布文件加受控文件水印");
String fileName = null;
BpiFileInfo bpiFileInfo =event.getBpiFileInfo();
String filePath = event.getBpiFileInfo().getFilePath() ;
String fileType = event.getBpiFileInfo().getFileType();
if(fileType.equals("pdf")){
//pdf文件
log.info("直接加水印");
PDFUtils.addImgWaterMaker(filePath.replace(ServerPathUrl.ENV_URL , "D:"));
bpiFileInfo.setFilePath(CommUtil.filePathEncrypt(filePath));
bpiFileInfoMapper.updateByPrimaryKeySelective(bpiFileInfo);
}else if (fileType.equals("doc")||fileType.equals("docx")){
//word文件
log.info("word转pdf加水印");
try {
fileName = PDFUtils.wordToPdf(filePath.replace(ServerPathUrl.ENV_URL , "D:"));
} catch (IOException e) {
throw new BizException(APIErrorCode.code.code500.getValue(),e.getMessage());
}
PDFUtils.addImgWaterMaker(fileName);
bpiFileInfo.setFilePath(CommUtil.filePathEncrypt(fileName.replace("D:",ServerPathUrl.ENV_URL)));
String[] ssa12 = fileName.split("/");
bpiFileInfo.setFileName( ssa12[ssa12.length-1]);
bpiFileInfo.setFileType("pdf");
bpiFileInfoMapper.updateByPrimaryKeySelective(bpiFileInfo);
}
}
}
3.使用 ApplicationEventPublisher 对象发布事件
@Autowired
private ApplicationEventPublisher publisher;
@Override
@Transactional(rollbackFor = Exception.class)
public OutVO addFile(BpiFileInfo bpiFileInfo) {
log.info("业务流程添加文件{}", bpiFileInfo);
bpiFileInfo.setFileOrForm(0);
bpiFileInfoMapper.insertSelective(bpiFileInfo);
List<BpiFileInfo> list =
bpiFileInfoMapper.selectByForeignKey(bpiFileInfo.getForeignKey(), 0);
if (bpiFileInfo.getForeignKey().contains(IDPrefix.BP.getPre()) ||
bpiFileInfo.getForeignKey().contains(IDPrefix.ES.getPre())) {
publisher.publishEvent(new AsyncAddWatermarkEvent(bpiFileInfo));
}
return OutVO.ok(list);
}
当发布事件后,ApplicationListener就会监听到事件发布,处理此事件。