zoukankan      html  css  js  c++  java
  • spring-----mvc的反射调用

    这几天在看spring mvc 源码,一直很好奇它究竟在哪进行的反射调用,通过源码,仔细阅读,最后发现了调用位置在类

    InvocableHandlerMethod 的doInvoke 方法


    /**
    * Invoke the handler method with the given argument values.
    */
    @Nullable
    protected Object doInvoke(Object... args) throws Exception {
    ReflectionUtils.makeAccessible(getBridgedMethod());
    try {
    return getBridgedMethod().invoke(getBean(), args);
    }
    catch (IllegalArgumentException ex) {
    assertTargetBean(getBridgedMethod(), getBean(), args);
    String text = (ex.getMessage() != null ? ex.getMessage() : "Illegal argument");
    throw new IllegalStateException(formatInvokeError(text, args), ex);
    }
    catch (InvocationTargetException ex) {
    // Unwrap for HandlerExceptionResolvers ...
    Throwable targetException = ex.getTargetException();
    if (targetException instanceof RuntimeException) {
    throw (RuntimeException) targetException;
    }
    else if (targetException instanceof Error) {
    throw (Error) targetException;
    }
    else if (targetException instanceof Exception) {
    throw (Exception) targetException;
    }
    else {
    throw new IllegalStateException(formatInvokeError("Invocation failure", args), targetException);
    }
    }
    }


    doInvoke又是在哪调用的呢?在同类的方法类
    @Nullable
    public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
    Object... providedArgs) throws Exception {

    Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
    if (logger.isTraceEnabled()) {
    logger.trace("Arguments: " + Arrays.toString(args));
    }
    return doInvoke(args);
    }

    invokeForRequest 又是在哪里调用的呢?
    在 ServletInvocableHandlerMethod 类的
    /**
    * Invoke the method and handle the return value through one of the
    * configured {@link HandlerMethodReturnValueHandler HandlerMethodReturnValueHandlers}.
    * @param webRequest the current request
    * @param mavContainer the ModelAndViewContainer for this request
    * @param providedArgs "given" arguments matched by type (not resolved)
    */
    public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
    Object... providedArgs) throws Exception {

    Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
    setResponseStatus(webRequest);

    if (returnValue == null) {
    if (isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) {
    mavContainer.setRequestHandled(true);
    return;
    }
    }
    else if (StringUtils.hasText(getResponseStatusReason())) {
    mavContainer.setRequestHandled(true);
    return;
    }

    mavContainer.setRequestHandled(false);
    Assert.state(this.returnValueHandlers != null, "No return value handlers");
    try {
    this.returnValueHandlers.handleReturnValue(
    returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
    }
    catch (Exception ex) {
    if (logger.isTraceEnabled()) {
    logger.trace(formatErrorForReturnValue(returnValue), ex);
    }
    throw ex;
    }
    }


    invokeAndHandle 是在哪里调用的?RequestMappingHandlerAdapter
    /**
    * Invoke the {@link RequestMapping} handler method preparing a {@link ModelAndView}
    * if view resolution is required.
    * @since 4.2
    * @see #createInvocableHandlerMethod(HandlerMethod)
    */
    @Nullable
    protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
    HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

    ServletWebRequest webRequest = new ServletWebRequest(request, response);
    try {
    WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
    ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);

    ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
    if (this.argumentResolvers != null) {
    invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
    }
    if (this.returnValueHandlers != null) {
    invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
    }
    invocableMethod.setDataBinderFactory(binderFactory);
    invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);

    ModelAndViewContainer mavContainer = new ModelAndViewContainer();
    mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
    modelFactory.initModel(webRequest, mavContainer, invocableMethod);
    mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);

    AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response);
    asyncWebRequest.setTimeout(this.asyncRequestTimeout);

    WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
    asyncManager.setTaskExecutor(this.taskExecutor);
    asyncManager.setAsyncWebRequest(asyncWebRequest);
    asyncManager.registerCallableInterceptors(this.callableInterceptors);
    asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);

    if (asyncManager.hasConcurrentResult()) {
    Object result = asyncManager.getConcurrentResult();
    mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0];
    asyncManager.clearConcurrentResult();
    LogFormatUtils.traceDebug(logger, traceOn -> {
    String formatted = LogFormatUtils.formatValue(result, !traceOn);
    return "Resume with async result [" + formatted + "]";
    });
    invocableMethod = invocableMethod.wrapConcurrentResult(result);
    }

    invocableMethod.invokeAndHandle(webRequest, mavContainer);
    if (asyncManager.isConcurrentHandlingStarted()) {
    return null;
    }

    return getModelAndView(mavContainer, modelFactory, webRequest);
    }
    finally {
    webRequest.requestCompleted();
    }
    }


    好了跟踪调用完毕。




  • 相关阅读:
    【三中校内训练】怎样更有力气
    【四校联考】立方体
    【四校联考】点
    第11章 卷积神经网络(CNNs)
    第10章神经网络基础
    在jupyter中配置python3
    第9章 优化方法和归一化
    第8章 参数化学习(parameterized learning)
    第7章 你的第一个分类器
    第6章 配置开发环境
  • 原文地址:https://www.cnblogs.com/anyehome/p/10385697.html
Copyright © 2011-2022 走看看