Application Events and Listeners

1、自定义事件和监听

1.1、定义事件

 package com.cjs.boot.event;

 import lombok.Data;
import org.springframework.context.ApplicationEvent; @Data
public class BlackListEvent extends ApplicationEvent { private String address; public BlackListEvent(Object source, String address) {
super(source);
this.address = address;
}
}

1.2、定义监听

 package com.cjs.boot.event;

 import org.springframework.context.ApplicationListener;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component; public class BlackListListener implements ApplicationListener<BlackListEvent> { @Override
public void onApplicationEvent(BlackListEvent event) {
System.out.println("监听到BlackListEvent事件: " + event.getAddress());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

1.3、注册监听

 package com.cjs.boot;

 import com.cjs.boot.event.BlackListListener;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.server.ErrorPage;
import org.springframework.boot.web.server.ErrorPageRegistrar;
import org.springframework.boot.web.server.ErrorPageRegistry;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpStatus;
import org.springframework.scheduling.annotation.EnableAsync; @SpringBootApplication
public class CjsSpringbootExampleApplication { public static void main(String[] args) { SpringApplication springApplication = new SpringApplication(CjsSpringbootExampleApplication.class);
springApplication.addListeners(new BlackListListener());
springApplication.run(args); }

1.4、发布事件

 package com.cjs.boot.controller;

 import com.cjs.boot.event.BlackListEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; @RestController
@RequestMapping("/activity")
public class ActivityController { // @Autowired
// private ApplicationEventPublisher publisher; @Autowired
private ApplicationContext publisher; @GetMapping("/sayHello.json")
public void sayHello() { /**
* You may register as many event listeners as you wish, but note that by default event listeners receive events synchronously.
* This means the publishEvent() method blocks until all listeners have finished processing the event.
*/ BlackListEvent event = new BlackListEvent(this, "abc@126.com");
publisher.publishEvent(event);
System.out.println("事件发布成功");
} }

2、基于注解的事件监听

package com.cjs.boot.event;

import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component; @Component
public class BlackListListener { @EventListener
public void processBlackListEvent(BlackListEvent event) {
System.out.println(123);
}
} --- package com.cjs.boot; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
public class CjsSpringbootExampleApplication { public static void main(String[] args) {
SpringApplication.run(CjsSpringbootExampleApplication.class, args);
} }

3、异步监听

 @EventListener
@Async
public void processBlackListEvent(BlackListEvent event) {
// BlackListEvent is processed in a separate thread
}

4、应用

 import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component; import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger; /**
* 批量送券
*/
@Slf4j
@Component
public class BatchSendCouponListener { @Autowired
private CouponPresentLogService couponPresentLogService; @Async
@EventListener
public void processBatchSendCouponEvent(BatchSendCouponEvent batchSendCouponEvent) {
Long cpId = batchSendCouponEvent.getCouponPresentId();
log.info("收到BatchSendCouponEvent, cpId={}", cpId);
List<CouponPresentLogEntity> list = couponPresentLogService.selectByPid(cpId); handle(cpId, list, 0);
} private void handle(Long cpId, List<CouponPresentLogEntity> list, int times) {
if (times >= 2) {
log.info("超过重试次数退出, cpId: {}, 剩余: {}", cpId, list.size());
return;
} List<Future<CouponPresentLogEntity>> futureList = new ArrayList<>(); for (CouponPresentLogEntity entity : list) {
futureList.add(couponPresentLogService.present(entity));
} AtomicInteger count = new AtomicInteger(0);
// 收集失败的
List<CouponPresentLogEntity> failList = new ArrayList<>();
for (Future<CouponPresentLogEntity> future : futureList) {
try {
CouponPresentLogEntity couponPresentLogEntity = future.get();
if (couponPresentLogEntity.getStatus() != PresentStatusEnum.SUCCESS.getType().intValue()) {
failList.add(couponPresentLogEntity);
}
count.getAndIncrement();
if (count.intValue() >= list.size()) {
List<CouponPresentLogEntity> failPresentLogList = couponPresentLogService.selectFailLogByPid(cpId);
if (null != failPresentLogList && failPresentLogList.size() > 0) {
times++;
log.info("第{}次重试, CPID: {}, 总计: {}, 失败: {}", times, cpId, list.size(), failPresentLogList.size());
handle(cpId, failPresentLogList, times);
}
}
} catch (InterruptedException e) {
log.error(e.getMessage(), e);
} catch (ExecutionException e) {
log.error(e.getMessage(), e);
}
}
} }
 import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service; import javax.annotation.Resource;
import java.util.concurrent.*; @Service
@Slf4j
public class CouponPresentLogServiceImpl implements CouponPresentLogService { @Autowired
private CouponPresentLogDao couponPresentLogDao;
@Resource
private CouponSendRpcService couponSendRpcService; @Async("myThreadPoolTaskExecutor")
@Override
public Future<CouponPresentLogEntity> present(CouponPresentLogEntity entity) {
try {
CouponBaseResponse rst = couponSendRpcService.send(entity.getUserId(), entity.getCouponBatchKey(), "1", entity.getVendorId());
if (null != rst && rst.isSuccess()) {
entity.setStatus(PresentStatusEnum.SUCCESS.getType());
entity.setFailureReason(PresentStatusEnum.SUCCESS.getName());
}else {
String reason = (null == rst) ? "响应异常" : rst.getMsg();
entity.setFailureReason(reason);
entity.setStatus(PresentStatusEnum.FAILURE.getType());
}
}catch (Exception ex) {
log.error(ex.getMessage(), ex);
entity.setFailureReason(ex.getMessage());
entity.setStatus(PresentStatusEnum.FAILURE.getType());
}
couponPresentLogDao.update(entity); return new AsyncResult<CouponPresentLogEntity>(entity);
} }

5、统计异步任务执行的进度

利用Future获取执行结果,比如上面的例子中,由于不是直接提交的任务,所以用AsyncResult来返回结果

上面的例子中,一个大任务,然后下面有许多子任务。在主任务中,统计各子任务的执行情况,是成功还是失败,然后统计成功多少,失败多少

也可以这样写:

@Autowired
ThreadPoolTaskExecutor taskExecutor; Future<Object> future = taskExecutor.submit(new Callable<Object>() {
@Override
public Object call() throws Exception {
return null;
}
});
 

Spring Boot 事件和监听的更多相关文章

  1. 【spring源码学习】spring的事件发布监听机制源码解析

    [一]相关源代码类 (1)spring的事件发布监听机制的核心管理类:org.springframework.context.event.SimpleApplicationEventMulticast ...

  2. Spring笔记(7) - Spring的事件和监听机制

    一.背景 事件机制作为一种编程机制,在很多开发语言中都提供了支持,同时许多开源框架的设计中都使用了事件机制,比如SpringFramework. 在 Java 语言中,Java 的事件机制参与者有3种 ...

  3. Spring Boot实现一个监听用户请求的拦截器

    项目中需要监听用户具体的请求操作,便通过一个拦截器来监听,并继续相应的日志记录 项目构建与Spring Boot,Spring Boot实现一个拦截器很容易. Spring Boot的核心启动类继承W ...

  4. rabbitMq与spring boot搭配实现监听

    在我前面有一篇博客说到了rabbitMq实现与zk类似的watch功能,但是那一篇博客没有代码实例,后面自己补了一个demo,便于理解.demo中主要利用spring boot的配置方式, 一.消费者 ...

  5. Spring boot设置启动监听端口

    一.通过配置 修改application.properties 在属性文件中添加server.port=8000 二.直接看代码: @Controller @EnableAutoConfigurati ...

  6. Spring Boot(六)自定义事件及监听

    事件及监听并不是SpringBoot的新功能,Spring框架早已提供了完善的事件监听机制,在Spring框架中实现事件监听的流程如下: 自定义事件,继承org.springframework.con ...

  7. 深入理解Spring的容器内事件发布监听机制

    目录 1. 什么是事件监听机制 2. JDK中对事件监听机制的支持 2.1 基于JDK实现对任务执行结果的监听 3.Spring容器对事件监听机制的支持 3.1 基于Spring实现对任务执行结果的监 ...

  8. 【laravel】Eloquent 模型事件和监听方式

    所有支持的模型事件 在 Eloquent 模型类上进行查询.插入.更新.删除操作时,会触发相应的模型事件,不管你有没有监听它们.这些事件包括: retrieved 获取到模型实例后触发 creatin ...

  9. uniapp仿h5+fire自定义事件触发监听

    仿h5+fire自定义事件触发监听 uni-app调用 event.js 源码记录(点击查看) 1.js下载地址 [event.js](https://ext.dcloud.net.cn/plugin ...

随机推荐

  1. NSData 与 struct 以及XML的转换。

    在做OC与C++ 混编的时候,我们可能会用到struct 与NSData的相互转换.在这里做一个记录 1.struct转换为NSData 例如如下的struct: struct tagPackageH ...

  2. 【shell脚本练习】批量添加用户和设置密码

    题目 添加9个用户,user101-user109:密码同用户名: 思路 for循环来添加就好了,用户名和密码都可以拼字符串来完成 user10+数字 要判断是否能添加成功,注意非交互模式下修改用户密 ...

  3. Linux搭建GIT 使用Eclipse创建并上传Git项目 EGit操作

    Linux搭建Git 1. gitblit服务器文档 http://gitblit.com/setup_go.html 2. 安装jdk 参考 http://blog.csdn.net/jerome_ ...

  4. Xcode相关常用快捷键搜集

    command + L:  跳转到指定行     control + i:  格式化代码 command + control + 上/下 在*.h和*.m之间切换. command + control ...

  5. mysql进阶(二十)CPU超负荷异常情况

    CPU超负荷异常情况 问题 项目部署阶段,提交订单时总是出现cpu超负荷工作情况,导致机器卡死,订单提交失败.通过任务管理器可见下图所示: 通过任务管理器中进程信息(见下图)进行查看,可见正是由于项目 ...

  6. STL算法设计理念 - 预定义函数对象

    预定义函数对象基本概念:标准模板库STL提前定义了很多预定义函数对象 1)使用预定义函数对象: #include <iostream> #include <cstdio> #i ...

  7. 【一天一道LeetCode】 #1 Two Sum

    一天一道LeetCode系列 (一)题目 Given an array of integers, return indices of the two numbers such that they ad ...

  8. Concurrent包常用方法简介

    1 Executor接口 留给开发者自己实现的接口,一般情况下不需要再去实现.它只有一个方法 void execute(Runnable command) 2 ExecutorService接口 它继 ...

  9. Android特效专辑(十)——点击水波纹效果实现,逻辑清晰实现简单

    Android特效专辑(十)--点击水波纹效果实现,逻辑清晰实现简单 这次做的东西呢,和上篇有点类似,就是用比较简单的逻辑思路去实现一些比较好玩的特效,最近也是比较忙,所以博客更新的速度还得看时间去推 ...

  10. 【Matlab编程】Matlab高效编程技巧

    1.默认状态下,matlab显示精度是short型,而默认的计算精度是double型,并且显示精度与计算精度没有关系. 2. 一只失明的猫的问题:注意方法! 3.给数组预分配空间是基本的高效编程准则之 ...