ApplicationEvent和Listener是Spring提供的一个事件发布与监听机制,底层采用的观察者模式实现,可以很方便的实现业务逻辑的解耦,提高程序的可扩展性和阅读性。
一、自定义发布事件
1、自定义类继承ApplicationEvent类,重载构造函数
/**
* 业务日志发布事件
*
* @Author YUBIN
* @create 2019-06-15
*/
@Getter
public class BusinessLogEvent extends ApplicationEvent {
private BusinessLogDto businessLogDto;
public BusinessLogEvent(Object source, BusinessLogDto businessLogDto) {
super(source);
this.businessLogDto = businessLogDto;
}
}
2、dto类的书写
/**
* 业务处理日志dto类
*
* @Author YUBIN
* @create 2019-06-15
*/
@Getter
@Setter
public class BusinessLogDto {
// 业务类型
private String type;
// 业务处理时长
private long businessTime;
// 业务处理结果
private String result;
// 请求参数
private String params;
}
3、书写相关业务类发布事件
发布事件采用的是applicationContext.pushEvent(....)
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private ApplicationContext applicationContext;
@Override
public BaseResponse pushOrder(Order order) {
BaseResponse response = new BaseResponse();
response.setCode(1);
response.setMessage("SUCCESS");
// 业务处理相关 ....
BusinessLogDto dto = new BusinessLogDto(BusinessType.PUSH_ORDER.getType(), JSON.toJSONString(response), JSON.toJSONString(order));
applicationContext.publishEvent(new BusinessLogEvent(this, dto));
return response;
}
}
二、注册监听
1、使用实现ApplicationListener接口的形式注册监听
/**
* 注册业务处理日志事件监听器
*
* @Author YUBIN
* @create 2019-06-15
*/
@Component // 将此类交给spring管理,就无需在手动的在SpringApplication中去注册了
@Slf4j
public class RegisterListener implements ApplicationListener<BusinessLogEvent> {
@Override
public void onApplicationEvent(BusinessLogEvent businessLogEvent) {
BusinessLogDto businessLogDto = businessLogEvent.getBusinessLogDto();
log.info(String.format("RegisterListener 接收到的监听数据是: %s", JSON.toJSONString(businessLogDto)));
}
}
使用实现ApplicationListener接口的形式,在注册监听器的时候,除了在该类上加上@Component注解交给sPRING管理之外,还可以通过SpringApplication.addListeners(...) 或SpringApplicationBuilder.listeners(...)方法注册它们。也可以通过将META-INF / spring.factories文件添加到项目中,并使用org.springframework.context.ApplicationListener引用你的监听器。 org.springframework.context.ApplicationListener=com.yubin.springboot.listener.RegisterListener
2、使用注解@EventListener实现监听
/**
* 使用注解的形式注解监听器
*
* @Author YUBIN
* @create 2019-06-15
*/
@Component
@Slf4j
public class AnnotationRegisterListener {
/**
* 注册监听实现方法
* @param businessLogEvent 业务处理推送事件
*/
@EventListener
public void register(BusinessLogEvent businessLogEvent) {
// 获取业务处理日志对象
BusinessLogDto businessLogDto = businessLogEvent.getBusinessLogDto();
//../省略逻辑
//输出业务处理日志信息
log.info(String.format("AnnotationRegisterListener 接收到的监听数据是: %s", JSON.toJSONString(businessLogDto)));
}
}
如果在你的项目中存在多个监听器,你想按照你的设想去定义监听器的执行顺序,可以通过在类上增加@Order注解来定义
三、使用@Async实现异步监听
@Aysnc其实是Spring内的一个组件,可以完成对类内单个或者多个方法实现异步调用,这样可以大大的节省等待耗时。内部实现机制是线程池任务ThreadPoolTaskExecutor,通过线程池来对配置@Async的方法或者类做出执行动作。
1、书写异步线程池配置类
/**
* 监听器异步线程池配置类
*
* @Author YUBIN
* @create 2019-06-16
*/
@Configuration
@EnableAsync
public class ListenerAsyncConfiguration implements AsyncConfigurer {
/**
* 获取异步线程池执行对象
* @return
*/
@Override
public Executor getAsyncExecutor() {
//使用Spring内置线程池任务对象
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
//设置线程池参数
taskExecutor.setCorePoolSize(5);
taskExecutor.setMaxPoolSize(10);
taskExecutor.setQueueCapacity(25);
taskExecutor.initialize();
return taskExecutor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
}
}
2、在需要的方法上加上@Async注解
@Component // 将此类交给spring管理,就无需在手动的在SpringApplication中去注册了
@Slf4j
@Order(0)
public class RegisterListener implements ApplicationListener<BusinessLogEvent> {
@Override
@Async
public void onApplicationEvent(BusinessLogEvent businessLogEvent) {
try {
Thread.sleep(10000); // 使当前线程休眠10s
} catch (InterruptedException e) {
e.printStackTrace();
}
BusinessLogDto businessLogDto = businessLogEvent.getBusinessLogDto();
log.info(String.format("RegisterListener 接收到的监听数据是: %s", JSON.toJSONString(businessLogDto)));
}
}
网友评论