春のインターセプト要求元の追跡。

春のインターセプト法(学びたいと思っていたHandlerMethodArgumentResolver、何の実行を走ったんオンラインチュートリアルによると、その後、)ので、次回は忘れて、問題は、それを記録場所を確認するために、長い時間のためにムッデバッグのソースコードを試してみました。

メソッドインターセプター


@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
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);
    }

}

インターセプト方法

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

これは間違っていない、次は、ソース・プロセスで、ダウンして行くと見た後、config設定addArgumentResolvers方法から壊れステップバイステップ、およびマーク。

RequestMappingHandlerAdapterへの私たちのMyUserArgumentResolverはまた、戻り値メソッドの傍受などの他のインターセプタの多くを保存し、クラス内に格納されています。

 

その後、我々は方法が傍受要求し、それがこのコレクション内のcustomArgumentRevolversから私たちの迎撃に出てくる際に参照してください。

1.すべての要求は、総DispatcherServletのスケジューラクラスにあり、サーブレットであります

2.それはSerlvetまあですので、最初のいくつかの前処理を行うために、主の方法でdoService方法、春を呼びます。主な治療は、いくつかのreqeust.setAttributeを行うことです

方法で本発明の方法は、上記RequestMappingHandlerAdapterを得るdoDispatcher 3.コールクラス、処理インターセプタ。

mapperHandlerは彼がビューの名前からイベント処理の実行クラスのチェーンで、HanderExecutionChainクラスで、彼はインターセプタをたくさん持っているという事実が対処する必要があります。

プロセッサはチェーンハンドラはパラメータとして渡す得るためにしながら、RequestMappingHandlerAdapterを取得するgetHandlerAdapterメソッドを呼び出し、その後、何この投手はありますか?内側の方法をどうするかを見てください。

 

ハンドラはでアプローチのコントローラです。

requestmappingHandlerAdapterは常にメソッドにtrueを返します。

 

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

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

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

 

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

 

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

 

 

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

 

 

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

 

おすすめ

転載: blog.csdn.net/helianus/article/details/81451517