spring intercept request source tracking.

Had wanted to learn about spring intercept method ( HandlerMethodArgumentResolver ), then according to the online tutorial ran down, no run, tried for a long time, huff debugging source code to see where the problem, record it, so next time forgot.

Methods interceptor


@Component
public class MyUserArgumentResolver implements HandlerMethodArgumentResolver{

    /**
     *  MethodParameter方法参数对象 通过它可以获取该方法参数上的一些信息 如方法参数中的注解信息等
     *  通过该方法我们如果需要对某个参数进行处理  只要此处返回true即可 如对Date类型数据处理的话
     *
     * @param methodParameter
     * @return
     */
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        System.out.println(this.getClass().getName());
        //方法上面带有@Call注解的都需要被拦截下来。
        return methodParameter.getMethodAnnotation(Call.class) != null;
    }

    /**
     * 真正用于处理参数分解的方法,返回的Object就是controller方法上的形参对象。
     * @param parameter
     * @param mavContainer
     * @param webRequest
     * @param binderFactory
     * @return
     * @throws Exception
     */
    @Override
    public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
        System.out.println("自己的业务逻辑");
        return null;
    }

}

 

config configuration


@Configuration
public class DevConfig implements WebMvcConfigurer {

    @Autowired
    private MyUserArgumentResolver myUserArgumentResolver;

    /**
     * 添加拦截器
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    }

    /**
     * 方法拦截
     * @param resolvers
     */
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(myUserArgumentResolver);
    }

}

Intercepted method

@PostMapping(value = "a")
    @Call
    public String a(User user){
        return "hello world";
    }

This is not wrong, the following is the source process, marked break from the config configuration addArgumentResolvers method, step by step, and then go down and see.

Our MyUserArgumentResolver to RequestMappingHandlerAdapter is stored inside the class which also saved a lot of other interceptors, such as the return value method interception.

 

Then we request method intercepted and see when it will come up with our interceptor from customArgumentRevolvers this collection inside.

1. All requests are to the total DispatcherServlet scheduler class is a Servlet,

2. Since it is Serlvet Well, first call doService method, spring mainly in the method to do some pre-processing. The main treatment is to do some reqeust.setAttribute

3. Call class doDispatcher present method, in the method to obtain the above RequestMappingHandlerAdapter, processing interceptor.

mapperHandler is a HanderExecutionChain class, he is a chain of event processing execution class from the name of view, the fact that he has a lot of interceptor need to be addressed.

Then call getHandlerAdapter method to get to RequestMappingHandlerAdapter, while the processor to get the chain Handler pass in as a parameter, then what this Hander is it? Look at what to do with the methods inside.

 

handler is the approach controller in.

requestmappingHandlerAdapter always returns true for the method.

 

下面开始解析,调用requestmappingHandlerAdapter的handle方法

一路跟进去会找到一个叫invokeHandlerMethod的方法,这个方法做了很多的处理,并且最终返回一个ModelAndVIew,这个类是spring处理结果之后最终返回的类,所以在这里方法里面应该有调用我们的方法拦截。
 

一步步跟进来终于能明眼看到我们的方法拦截器了,但是等等!上面是个什么鬼!这么还有那么多东西,然后你会发现很多都是你熟悉的东西,比如下标为1的RequestParamMapMethodResolver,这个看着很眼熟,会不会和@RequestParam注解有关系的,马上搜一下源码看看。

 

看到这个源码,我相信大家都知道了前因后果了,原来@RequestParam也是一个方法拦截器,和我们定义的其实一模一样。还有那些@RequestBody,@CookieValue等等只要spring允许在方法上面注释的基本上都有自己对应的拦截器,你请求这些方法,spring都会遍历一遍这个拦截器,然后找自己对于的注解,只要是自己处理的注解,那么就会把方法拦截下来交给自己对应的拦截器做处理,同是返回结果。到底是不是这样呢,我们来验证一下,继续往下走。

 

上面巴拉巴拉一大堆,下面真正进入controller方法级别的一些处理。

 

 

在controller执行之前看到了我们的拦截器,但是我们的拦截器在太后面了,所以,如果被前面的一些方法拦截到了,也就是如果我们加了@RequestParam的话,就会被@RequestParam方法给拦截下来,处理完之后返回相应的返回值。我们自己的就不会生效。到此一次controller请求,基本都看到了spring的请求处理的大致过程。

 

 

处理完之后返回的页面结果,spring对controller的返回值也有会对应的handler,到此就不在深入。

 

Guess you like

Origin blog.csdn.net/helianus/article/details/81451517