Springmvc源码解析---执行流程(2)

面试题:当接口定义的是下面这种方式的时候是用什么调用的?为什么?如何调用的?

@Controller
public class UserController {
    @RequestMapping("/getUser")
    public Object getUser(String name){
        System.out.println("getuser");
        return "success";
    }
}

我们试想一下,一个类调用另一个类有几种方法,一是通过new一个类,再去调用,但是在DispatcherServlet里new一个类不现实,因为它根本不知道你定义的类名;二是通过继承一个类然后实现它,也就是上面所讲的,但它是有弊端的,一个类只能写一个接口,有多少个接口就有多少个类,那么剩下的就只能是反射了

直接到doDispatch方法中

org.springframework.web.servlet.DispatcherServlet#doDispatch

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    HttpServletRequest processedRequest = request;
    HandlerExecutionChain mappedHandler = null;
    boolean multipartRequestParsed = false;
    WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

    try {
        try {
            ModelAndView mv = null;
            Object dispatchException = null;

            try {
                processedRequest = this.checkMultipart(request);
                multipartRequestParsed = processedRequest != request;
                
				//获取映射器,这里获取的是RequestMappingHandlerMapping
                mappedHandler = this.getHandler(processedRequest);
                if (mappedHandler == null) {
                    this.noHandlerFound(processedRequest, response);
                    return;
                }

                //同样的,适配器也变成RequestMappingHandlerAdapter 
                HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
                
                String method = request.getMethod();
                boolean isGet = "GET".equals(method);
                if (isGet || "HEAD".equals(method)) {
                    long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                    if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet
                    {
                        return;
                    }
                }
                if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                    return;
                }
                
				//调用自己写的处理器
                mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
                
                if (asyncManager.isConcurrentHandlingStarted()) {
                    return;
                }
                this.applyDefaultViewName(processedRequest, mv);
                mappedHandler.applyPostHandle(processedRequest, response, mv);
            } catch (Exception var20) {
                dispatchException = var20;
            } catch (Throwable var21) {
                dispatchException = new NestedServletException("Handler dispatch failed", var21);
            }
            //对返回的数据进行视图解析,跟(1)一样
            this.processDispatchResult(processedRequest, response, mappedHandler, mv,(Exception)dispatchException);
        } catch (Exception var22) {
            this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);
        } catch (Throwable var23) {
            this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));
        }
    } finally {
        if (asyncManager.isConcurrentHandlingStarted()) {
            if (mappedHandler != null) {
                mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
            }
        } else if (multipartRequestParsed) {
            this.cleanupMultipart(processedRequest);
        }
    }
}

这里主要看一下 ha.handle()方法:

org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#handle

@Nullable
public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
	//调用一个本类的方法
    return this.handleInternal(request, response, (HandlerMethod)handler);
}

handleInternal()

org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#handleInternal

protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
    this.checkRequest(request);
    ModelAndView mav;
    if (this.synchronizeOnSession) {
        HttpSession session = request.getSession(false);
        // 是否通过 @SessionAttributes 注释声明了 session 属性。
        if (session != null) {
            Object mutex = WebUtils.getSessionMutex(session);
            synchronized(mutex) {
				//通过反射调用controller中的方法
                mav = this.invokeHandlerMethod(request, response, handlerMethod);
            }
        } else {
            mav = this.invokeHandlerMethod(request, response, handlerMethod);
        }
    } else {
        mav = this.invokeHandlerMethod(request, response, handlerMethod);
    }
    //......
    return mav;
}

invokeHandlerMethod

org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#invokeHandlerMethod
@Nullable
protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
    ServletWebRequest webRequest = new ServletWebRequest(request, response);
    Object result;
    try {
    
        //.....
        
        //重点是这一句,实际处理类,调用ServletInvocableHandlerMethod类的方法
        invocableMethod.invokeAndHandle(webRequest, mavContainer, new Object[0]);

        if (!asyncManager.isConcurrentHandlingStarted()) {
            ModelAndView var15 = this.getModelAndView(mavContainer, modelFactory, webRequest);
            return var15;
        }
        result = null;
    } finally {
        webRequest.requestCompleted();
    }
    return (ModelAndView)result;
}

invokeAndHandle

org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#invokeAndHandle

public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {

	//调用目标方法之后获取的返回值,在这里也就是方法中的 success
    Object returnValue = this.invokeForRequest(webRequest, mavContainer, providedArgs);

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

invokeForRequest

org.springframework.web.method.support.InvocableHandlerMethod#invokeForRequest

@Nullable
public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {

	//先获取方法中的参数
    Object[] args = this.getMethodArgumentValues(request, mavContainer, providedArgs);
    if (this.logger.isTraceEnabled()) {
        this.logger.trace("Arguments: " + Arrays.toString(args));
    }
    
    //获取参数,调用方法
    return this.doInvoke(args);
}

doInvoke

org.springframework.web.method.support.InvocableHandlerMethod#doInvoke
@Nullable
protected Object doInvoke(Object... args) throws Exception {
    ReflectionUtils.makeAccessible(this.getBridgedMethod());

    try {
    
       //通过反射invoke调用目标方法
       // getBridgedMethod()会获取到UserController类中的getUser()方法,this.getBean()就是UserController类,args为方法中的参数,即name
        return this.getBridgedMethod().invoke(this.getBean(), args);

    } catch (IllegalArgumentException var4) {
        this.assertTargetBean(this.getBridgedMethod(), this.getBean(), args);
        String text = var4.getMessage() != null ? var4.getMessage() : "Illegal argument";
        throw new IllegalStateException(this.formatInvokeError(text, args), var4);
    } catch (InvocationTargetException var5) {
        Throwable targetException = var5.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(this.formatInvokeError("Invocation failure", args), targetException);
        }
    }
}
上一篇:SpringMVC拦截器使用流程和源码分析


下一篇:第二十五章:责任链模式