拦截器如何在不阻止业务处理的情况下处理同步和异步请求?

时间:2019-10-11 13:45:10

标签: spring

我们已经开发了一个spring-mvc库,该库允许实现它的项目通过拦截器拦截查询中存在的信息(参数,方法名称,URI ...)。

此拦截器实现“ HandlerInterceptor”接口,更精确地实现“ afterCompletion”方法。然后,此信息将包含在另一个对象中,该对象将在RabbitMq消息队列中发送,以跟踪实现该库的项目中的所有Rest调用。

使用此拦截器的缺点是它是同步的,也就是说,如果同时接收到多个请求,则书商将阻止项目的业务流程。请注意,实现该库的项目处于同步模式,它们没有实现WebFlux,我们必须使用此约束。

目标是使库的使用对实现库的项目完全透明。 “ afterCompletion”方法中的处理不得阻止新的传入请求。

为解决此问题,我们尝试了几种解决方案,以使书商回馈业务领域:

  • 一个异步拦截器(HandlerInterceptorAdapter-afterConcurrentHandlingStarted),但它仅处理异步请求,因此此选择似乎不符合我们的约束。
  • @Async批注,但是即使使用该批注,处理仍保持同步。

您是否知道如何修改库以处理同步请求和异步请求,而又不阻塞调用项目的业务流程?

    @Configuration
    public class Config implements WebMvcConfigurer {

        private final Interceptor interceptor;

        @Autowired
        public Config(Interceptor interceptor) {
            this.interceptor = interceptor;
        }

        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(interceptor).excludePathPatterns("/error");
        }
    }
    @Component
    public class Interceptor implements HandlerInterceptor {

        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
            [...]

        }

    }

并且在使用库在项目上提供的注释时,调用sycnhrone查询会阻止后者的处理:

   @GetMapping("/hello/{param}")
   @MYANNOTATION
    public String helloWord(@PathVariable String param) {
       [... a long treatment]
    }

0 个答案:

没有答案