当一次请求中的某些流程只需要执行,不需要结果时,可以考虑将这些流程的执行放到异步线程去执行,可以使用spring上下文自带的事件发布与监听去实现。
spring上下文工具类
/**
* spring上下文工具类
*/
@Component
@Lazy(false)
public class SpringContextUtils implements ApplicationContextAware, DisposableBean {
private static ApplicationContext applicationContext = null;
@Override
public void destroy() throws Exception {
applicationContext = null;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextUtils.applicationContext = applicationContext;
}
/**
* 发布事件
*
* @param event
*/
public static void publishEvent(ApplicationEvent event) {
if (applicationContext == null) {
return;
}
applicationContext.publishEvent(event);
}
}
@Lazy代表延时加载,默认是true
- lazy=false,代表不延时,如果对象A中还有对象B的引用,会在A的xml映射文件中配置b的对象引用,多对一或一对多,不延时代表查询出对象A的时候,会把B对象也查询出来放到A对象的引用中,A对象中的B对象是有值的。
- lazy=true代表延时,查询A对象时,不会把B对象也查询出来,只会在用到A对象中B对象时才会去查询。
发布,监听事件demo
/**
* 事件发布demo
*/
@Slf4j
public class DemoEvent extends ApplicationEvent {
private String str;
public DemoEvent(String str) {
super(str);
this.str = str;
}
public static void publishEvent(String str) {
SpringContextUtils.publishEvent(new DemoEvent(str));
}
/**
* 异步监听
*/
@Component
@Slf4j
public static class DemoListener {
@Async
@EventListener
public void listenEvent(DemoEvent event) {
log.info(JSONObject.toJSON(event).toString());
}
}
}
调用
@RestController
@Slf4j
public class DemoController {
@GetMapping("demo")
public BaseResponse demo(String str) throws Exception{
DemoEvent.publishEvent(str);
Thread.sleep(2000); //可以看到睡眠时监听事件处会正常执行
log.info("str:{}",str);
return ResponseUtils.buildSuccess();
}
}