mvc源码流程

流程图
在这里插入图片描述
核心:
1.DispatcherServlet 前端控制器
2.HandlerMapping 处理器映射器
3.HandlerAdapter 处理器适配器
4.ViewResolver 视图解析器
5.View 视图对象

SpringMVC执行流程源码分析
前提要求
在controller中写好一个接口

@RestController
@RequestMapping("/wdl")
public class TestController {

    @Autowired
    private TestApplicationContextAware app;

    @GetMapping("/test")
    public void test(){
        CareerService bean =(CareerService) app.getBean("programmerService");
        bean.entry();
    }
}

在项目启动的时候扫描controller中带有@GetMapping、PostMapping、DeleteMapping、PutMapping、RequestMapping的注解,并将这些注解所在的接口名称,接口地址、接口所在类封装到AbstractHandlerMethodMapping抽象类的register方法,在这个方法中会 封装好项目中所有的接口
源代码

public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMapping implements InitializingBean {
...
private final AbstractHandlerMethodMapping<T>.MappingRegistry mappingRegistry = new AbstractHandlerMethodMapping.MappingRegistry();

//在这个方法会存项目中所有的接口,并保存到mappingRegistry 中,方便接口请求时从这里面获取对应的执行方法
public void register(T mapping, Object handler, Method method) {
            this.readWriteLock.writeLock().lock();

            try {
                HandlerMethod handlerMethod = AbstractHandlerMethodMapping.this.createHandlerMethod(handler, method);
                this.validateMethodMapping(handlerMethod, mapping);
                Set<String> directPaths = AbstractHandlerMethodMapping.this.getDirectPaths(mapping);
                Iterator var6 = directPaths.iterator();

                while(var6.hasNext()) {
                    String path = (String)var6.next();
                    this.pathLookup.add(path, mapping);
                }

                String name = null;
                if (AbstractHandlerMethodMapping.this.getNamingStrategy() != null) {
                    name = AbstractHandlerMethodMapping.this.getNamingStrategy().getName(handlerMethod, mapping);
                    this.addMappingName(name, handlerMethod);
                }

                CorsConfiguration corsConfig = AbstractHandlerMethodMapping.this.initCorsConfiguration(handler, method, mapping);
                if (corsConfig != null) {
                    corsConfig.validateAllowCredentials();
                    this.corsLookup.put(handlerMethod, corsConfig);
                }

                this.registry.put(mapping, new AbstractHandlerMethodMapping.MappingRegistration(mapping, handlerMethod, directPaths, name, corsConfig != null));
            } finally {
                this.readWriteLock.writeLock().unlock();
            }

        }
}

在同一个类中,在接口请求之后,查询项目中这个接口的方法名、地址、所在类名
@Nullable
    protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
        List<AbstractHandlerMethodMapping<T>.Match> matches = new ArrayList();
        //这里就是从上面register注册的所有接口中获取本次请求的接口信息
        List<T> directPathMatches = this.mappingRegistry.getMappingsByDirectPath(lookupPath);
        .....
        }
``
`
接口请求源码分析
1DispatcherServlet接收到请求之后由doDispatch方法进行接收请求

```java
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;
                    mappedHandler = this.getHandler(processedRequest);//获取本次请求的接口执行者
                    if (mappedHandler == null) {
                        this.noHandlerFound(processedRequest, response);
                        return;
                    }

                    HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
                    String method = request.getMethod();
                    boolean isGet = HttpMethod.GET.matches(method);
                    //get方法增加判断,Spring MVC中,我们发出请求,就会返回view,而实际上这样就引出了一个问题:我的请求如果没有任何改变的话,也就是说上次请求获得的静态资源是没有变化的。此时按照Spring MVC的机制,我们仍然返回了一套静态资源。显然这样增加了服务器的负载,以及网络带宽的使用。所以如果时间戳相同的情况下,从缓存中获取视图
                    if (isGet || HttpMethod.HEAD.matches(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);
                }

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

        }
    }
	//获取执行者
@Nullable
    protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
        if (this.handlerMappings != null) {
            Iterator var2 = this.handlerMappings.iterator();

            while(var2.hasNext()) {
                HandlerMapping mapping = (HandlerMapping)var2.next();
                //获取接口的执行者,调用的接口HandlerMapping接口的getHandler方法,这个接口默认的实现类是AbstractHandlerMapping,由这个类的getHandler方法去前的AbstractHandlerMethodMapping抽象类中获取已经在项目启动的时候已经封装好的所有接口信息
                HandlerExecutionChain handler = mapping.getHandler(request);
                if (handler != null) {
                    return handler;
                }
            }
        }

        return null;
    }

在这里插入图片描述参考地址

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值