前两天有朋友面试“淘汰集团”,也就是“淘宝”+“天猫”的组合,最后被面试官问到了这道题:“你看过哪些开源框架的源码?举例说明一下”。
诚然,这是一道比较考验应聘者基本功的问题,也是很好区分“好学生”和“普通学生”的一道经典的开放性问题。
那这个问题应该怎么回答呢?
我这给大家提供两个思路吧:
Spring Boot 在收到请求之后,会先执行前端控制器 DispatcherServlet,并调用其父类 FrameworkServlet 中的 service 方法,其核心源码如下:
/** * Override the parent class implementation in order to intercept PATCH requests. */@Overrideprotected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpMethod httpMethod = HttpMethod.resolve(request.getMethod()); if (httpMethod == HttpMethod.PATCH || httpMethod == null) { processRequest(request, response); } else { super.service(request, response); }}
继续往下看,processRequest 实现源码如下:
protected final void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 省略一堆初始化配置 try { // 真正执行逻辑的方法 doService(request, response); } catch (ServletException | IOException ex) { ... }}
doService 实现源码如下:
protected abstract void doService(HttpServletRequest request, HttpServletResponse response) throws Exception;
doService 是抽象方法,由其之类 DispatcherServlet 来重写实现,其核心源码如下:
@Overrideprotected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception { // 省略初始化过程... try { doDispatch(request, response); } finally { // 省略其他... }}
此时就进入到了 DispatcherServlet 中的 doDispatch 方法了:
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { // 获取原生请求 HttpServletRequest processedRequest = request; // 获取Handler执行链 HandlerExecutionChain mappedHandler = null; // 是否为文件上传请求, 默认为false boolean multipartRequestParsed = false; WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); try { ModelAndView mv = null; Exception dispatchException = null; try { // 检查是否为文件上传请求 processedRequest = checkMultipart(request); multipartRequestParsed = (processedRequest != request); // Determine handler for the current request. // 获取能处理此请求的Handler mappedHandler = getHandler(processedRequest); if (mappedHandler == null) { noHandlerFound(processedRequest, response); return; } // Determine handler adapter for the current request. // 获取适配器 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // Process last-modified header, if supported by the handler. 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; } applyDefaultViewName(processedRequest, mv); mappedHandler.applyPostHandle(processedRequest, response, mv); } // 忽略其他...}
通过上述的源码我们可以看到,请求的核心代码都在 doDispatch 中,他里面包含的主要执行流程有以下这些:
Spring Cloud 组件有很多,你可以挑一个源码实现比较简单的组件来讲,这里推荐 Spring Cloud LoadBalancer,因为其核心源码的实现比较简单。
Spring Cloud LoadBalancer 中内置了两种负载均衡策略:
轮询负载均衡策略的核心实现源码如下:
// ++i 去负数,得到一个正数值int pos = this.position.incrementAndGet() & Integer.MAX_VALUE;// 正数值和服务实例个数取余 -> 实现轮询ServiceInstance instance = (ServiceInstance)instances.get(pos % instances.size());// 将实例返回给调用者return new DefaultResponse(instance);
随机负载均衡策略的核心实现源码如下:
// 通过 ThreadLocalRandom 获取一个随机数,最大值为服务实例的个数int index = ThreadLocalRandom.current().nextInt(instances.size());// 得到实例ServiceInstance instance = (ServiceInstance)instances.get(index);// 返回return new DefaultResponse(instance);
开源框架的源码在面试中经常会被问到,但只因如此,就去完整的看某个框架的源码,其实还是挺难的。第一,框架中的源码很多,很难一次性看懂。第二,即使能看懂,看完之后也会很快忘记(因为内容太多了)。此时,不如挑一些框架中的经典实现源码来看,其性价比更高,既能学到框架中的精髓,又能搞定面试,是一个不错的选择。
本文链接:http://www.28at.com/showinfo-26-19925-0.html阿里面试:看过框架源码吗?举例说明一下
声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com
上一篇: 十个使用Spring Cloud和Java创建微服务的实践案例
下一篇: Gorm 中的钩子和回调