如何在Spring Boot应用程序中定义拦截器的执行顺序?

时间:2015-09-19 08:14:35

标签: spring spring-boot

我定义了一个拦截器并将其注册到一个类(注释为Configuration)中,该类扩展了WebMvcConfigurerAdapter;但是,我也使用了一些第三方库,它们也定义了一些拦截器。我希望我的拦截器成为拦截器执行链中的最后一个。似乎没有办法强制执行此操作。如何在Spring Boot应用程序中定义拦截器的执行顺序?

3 个答案:

答案 0 :(得分:0)

如果我们有多个拦截器,我们可以执行以下操作,而不是@Order注释。

@EnableWebMvc
@Configuration
public class WebMVCConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry
            .addWebRequestInterceptor(new WebRequestInterceptor() {
                //Overrides
            }).order(Ordered.HIGHEST_PRECEDENCE);
        registry
           .addWebRequestInterceptor(new WebRequestInterceptor() {
                //Overrides
            }).order(Ordered.LOWEST_PRECEDENCE);
    }
}

答案 1 :(得分:0)

根据我的经验,拦截器正在添加堆栈。出于这个原因,您应该在调用之前添加一个想要注册的寄存器。

答案 2 :(得分:0)

所有Feign客户端都成为代理,所以只有一种方法可以改变请求拦截器的顺序。但是不能用,因为如果把代理改成SGLIB,就不行了。

    if(bean instanceof YoursFeignClientBean) {
        Class<Proxy> superclass = (Class<Proxy>) bean.getClass().getSuperclass();
        Field h =  superclass.getDeclaredField("h");
        h.setAccessible(true);

        // its FeignInvocationHandler
        InvocationHandler ih = (InvocationHandler) ReflectionUtils.getField(h, bean);
        Field dispatch = ih.getClass().getDeclaredField("dispatch");
        dispatch.setAccessible(true);

        Map<Method, InvocationHandlerFactory.MethodHandler> map =
                (Map<Method, InvocationHandlerFactory.MethodHandler>) dispatch.get(ih);

        for (Method method : map.keySet()) {
            InvocationHandlerFactory.MethodHandler handler = map.get(method);
            Field requestInterceptors = handler.getClass().getDeclaredField("requestInterceptors");
            requestInterceptors.setAccessible(true);

            List<RequestInterceptor> interceptorList = (List<RequestInterceptor>)
                    ReflectionUtils.getField(requestInterceptors, handler);

            RequestInterceptor ri =  interceptorList.stream().filter(t -> t.getClass().getName().startsWith(YoursFeignConfig.class.getName())).findFirst().get();

            // reorder
            interceptorList.remove(ri);
            interceptorList.add(ri);
        }