- 浏览: 273736 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
highphd:
海量用户如何处理啊?缓存服务器?大数据?
面向海量服务的设计原则和策略总结 -
AKka:
看了这篇博文更感觉到自己要学的东西更多了。同时感谢博主的辛勤写 ...
[Java性能剖析]JVM Management API -
sswh:
非常不错,感谢分享!!
[Java性能剖析]Sun JVM Attach API -
muyexi:
请问在Android开发中的什么场景下,会用到ObjectWe ...
[字节码系列]ObjectWeb ASM构建Method Monitor -
zoutuo:
前辈可否告知其中的“吞吐量”指的是什么?谢谢!
[Java性能剖析]Sun JVM内存管理和垃圾回收
4.请求-处理链映射(HandlerMapping)
HandlerMapping定义了请求与处理链之间的映射的策略,见如下接口。
public interface HandlerMapping { String PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE = HandlerMapping.class.getName() + ".pathWithinHandlerMapping"; HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception; }
主要的继承类和继承结构如下
其中
*AbstractHandlerMapping:定义了HandlerMapping实现的最基础的部分内容,包括拦截器列表和默认处理对象
*AbstractUrlHandlerMapping:在AbstractHandlerMapping的基础上,定义了从URL到处理对象的映射关系管理,其主要处理过程如下
getHandlerInternal:
protected Object getHandlerInternal(HttpServletRequest request) throws Exception { String lookupPath = this.urlPathHelper.getLookupPathForRequest(request); if (logger.isDebugEnabled()) { logger.debug("Looking up handler for [" + lookupPath + "]"); } Object handler = lookupHandler(lookupPath, request); if (handler == null) { // We need to care for the default handler directly, since we need to // expose the PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE for it as well. Object rawHandler = null; if ("/".equals(lookupPath)) { rawHandler = getRootHandler(); } if (rawHandler == null) { rawHandler = getDefaultHandler(); } if (rawHandler != null) { validateHandler(rawHandler, request); handler = buildPathExposingHandler(rawHandler, lookupPath); } } return handler; }
lookupHandler:
protected Object lookupHandler(String urlPath, HttpServletRequest request) throws Exception { // Direct match? Object handler = this.handlerMap.get(urlPath); if (handler != null) { validateHandler(handler, request); return buildPathExposingHandler(handler, urlPath); } // Pattern match? String bestPathMatch = null; for (Iterator it = this.handlerMap.keySet().iterator(); it.hasNext();) { String registeredPath = (String) it.next(); if (getPathMatcher().match(registeredPath, urlPath) && (bestPathMatch == null || bestPathMatch.length() < registeredPath.length())) { bestPathMatch = registeredPath; } } if (bestPathMatch != null) { handler = this.handlerMap.get(bestPathMatch); validateHandler(handler, request); String pathWithinMapping = getPathMatcher().extractPathWithinPattern(bestPathMatch, urlPath); return buildPathExposingHandler(handler, pathWithinMapping); } // No handler found... return null; }
另外,其定义了Handler的注册方法registerHandler
*AbstractDetectingUrlHandlerMapping:AbstractDetectingUrlHandlerMapping通过继承ApplicationObjectSupport实现了ApplicationContextAware接口,在初始化完成之后自动通过ApplicationObjectSupport.setApplicationContext-->AbstractDetectingUrlHandlerMapping.initApplicationContext-->AbstractDetectingUrlHandlerMapping.detectHandlers调用detectHandlers函数,该函数将注册到ApplicationContext的所有Bean对象逐一检查,由其子类实现的determineUrlsForHandler判断每个Bean对象对应的URL,并将URL与Bean的关系通过AbstractUrlHandlerMapping.registerHandler注册
protected void detectHandlers() throws BeansException { if (logger.isDebugEnabled()) { logger.debug("Looking for URL mappings in application context: " + getApplicationContext()); } String[] beanNames = (this.detectHandlersInAncestorContexts ? BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) : getApplicationContext().getBeanNamesForType(Object.class)); // Take any bean name or alias that begins with a slash. for (int i = 0; i < beanNames.length; i++) { String beanName = beanNames[i]; String[] urls = determineUrlsForHandler(beanName); if (!ObjectUtils.isEmpty(urls)) { // URL paths found: Let's consider it a handler. registerHandler(urls, beanName); } else { if (logger.isDebugEnabled()) { logger.debug("Rejected bean name '" + beanNames[i] + "': no URL paths identified"); } } } }
*BeanNameUrlHandlerMapping:非常简单,其实现determineUrlsForHandler函数,如果一个Bean以“/”开头,则认为是一个处理器类,并且以bean的名字作为映射的url,处理过程如下
protected String[] determineUrlsForHandler(String beanName) { List urls = new ArrayList(); if (beanName.startsWith("/")) { urls.add(beanName); } String[] aliases = getApplicationContext().getAliases(beanName); for (int j = 0; j < aliases.length; j++) { if (aliases[j].startsWith("/")) { urls.add(aliases[j]); } } return StringUtils.toStringArray(urls); }
*DefaultAnnotationHandlerMapping:实现determineUrlsForHandler函数,检查每个Bean对象的类或者方法有没有RequestMapping这个Annotation,如果有,则将相应配置的URL作为该Bean对应处理的URL,处理过程如下
protected String[] determineUrlsForHandler(String beanName) { ApplicationContext context = getApplicationContext(); Class<?> handlerType = context.getType(beanName); RequestMapping mapping = AnnotationUtils.findAnnotation(handlerType, RequestMapping.class); if (mapping == null && context instanceof ConfigurableApplicationContext && context.containsBeanDefinition(beanName)) { ConfigurableApplicationContext cac = (ConfigurableApplicationContext) context; BeanDefinition bd = cac.getBeanFactory().getMergedBeanDefinition(beanName); if (bd instanceof AbstractBeanDefinition) { AbstractBeanDefinition abd = (AbstractBeanDefinition) bd; if (abd.hasBeanClass()) { Class<?> beanClass = abd.getBeanClass(); mapping = AnnotationUtils.findAnnotation(beanClass, RequestMapping.class); } } } if (mapping != null) { // @RequestMapping found at type level this.cachedMappings.put(handlerType, mapping); Set<String> urls = new LinkedHashSet<String>(); String[] paths = mapping.value(); if (paths.length > 0) { // @RequestMapping specifies paths at type level for (String path : paths) { addUrlsForPath(urls, path); } return StringUtils.toStringArray(urls); } else { // actual paths specified by @RequestMapping at method level return determineUrlsForHandlerMethods(handlerType); } } else if (AnnotationUtils.findAnnotation(handlerType, Controller.class) != null) { // @RequestMapping to be introspected at method level return determineUrlsForHandlerMethods(handlerType); } else { return null; } }
5.处理器适配器(HandlerAdapter)
HandlerAdapter定义了处理类如何处理请求的策略,见如下接口
public interface HandlerAdapter { boolean supports(Object handler); ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception; long getLastModified(HttpServletRequest request, Object handler); }
通过实现特定的策略,可以灵活地将任意对象转换成请求处理对象,主要实现包括:
1)SimpleControllerHandlerAdapter/HttpRequestHandlerAdapter/SimpleServletHandlerAdapter/ThrowawayController
非常简单,面向实现实现了特定接口的处理类的情形,仅仅做一个代理执行处理,看一下其中SimpleControllerHandlerAdapter的代码如下,其特定处理实现了Controller接口的处理类
public class SimpleControllerHandlerAdapter implements HandlerAdapter { public boolean supports(Object handler) { return (handler instanceof Controller); } public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return ((Controller) handler).handleRequest(request, response); } public long getLastModified(HttpServletRequest request, Object handler) { if (handler instanceof LastModified) { return ((LastModified) handler).getLastModified(request); } return -1L; } }
2)AnnotationMethodHandlerAdapter
通过配置特定的Annotation,定义了该如何注入参数、调用哪个方法、对返回参数如何处理,主要过程如下(AnnotationMethodHandlerAdapter.invokeHandlerMethod)
try { ServletHandlerMethodResolver methodResolver = getMethodResolver(handler); Method handlerMethod = methodResolver.resolveHandlerMethod(request); ServletHandlerMethodInvoker methodInvoker = new ServletHandlerMethodInvoker(methodResolver); ServletWebRequest webRequest = new ServletWebRequest(request, response); ExtendedModelMap implicitModel = new ExtendedModelMap(); Object result = methodInvoker.invokeHandlerMethod(handlerMethod, handler, webRequest, implicitModel); ModelAndView mav = methodInvoker.getModelAndView(handlerMethod, result, implicitModel, webRequest); methodInvoker.updateSessionAttributes( handler, (mav != null ? mav.getModel() : null), implicitModel, webRequest); return mav; } catch (NoSuchRequestHandlingMethodException ex) { return handleNoSuchRequestHandlingMethod(ex, request, response); }
*ServletHandlerMethodResolver(AnnotationMethodHandlerAdapter内部类):该类通过请求URL、请求Method和处理类的RequestMapping定义,最终确定该使用处理类的哪个方法来处理请求
*ServletHandlerMethodInvoker(AnnotationMethodHandlerAdapter内部类):检查处理类相应处理方法的参数以及相关的Annotation配置,确定如何转换需要的参数传入调用方法,并最终调用返回ModelAndView
6.视图策略(ViewResolver)
ViewResolver定义了如何确定处理视图的View对象的策略,见如下接口
public interface ViewResolver { View resolveViewName(String viewName, Locale locale) throws Exception; }
发表评论
-
面向海量服务的设计原则和策略总结
2010-05-27 07:05 12770互联网服务的特点就是面向海量级的用户,面向海量级的 ... -
SpringMVC源码解析(上)
2009-05-22 10:03 47111.从DispatcherServlet开始 ... -
JSP2.1规范
2009-05-19 16:15 2290JSP2.1规范 -
Servlet2.3规范
2009-05-19 15:49 1400Servlet2.3规范 -
半年TeamLeader总结
2008-10-18 09:29 1959成为一个小团队的TeamLe ... -
两年前看到的帖子--10年跳槽总结出的珍贵经验
2008-06-27 09:12 2337首先,真正的高级人才 ... -
读书笔记——关于Annotation与XML配置
2008-06-19 22:06 1705随着Java5的流行,Annotation渐有取代 ... -
读书笔记——Spring扩展点
2008-06-19 21:51 3956Ø BeanPostProcessors :该扩 ... -
读书笔记——事务总结
2008-06-16 22:41 17651. 事务四要素( ACID ) Ø Atom ... -
最近学习计划-共勉
2008-06-16 22:40 15701.spring设计艺术 1)spring源码重读 ... -
AST构建Hibernat动态查询
2007-05-25 13:33 3096一、效果 java 代码 public cla ... -
FreeMarker对Template的加载过程
2007-03-10 09:55 5125前一阵子在研究使用数据库来配置表现层的信息的技 ... -
在FreeMarker3.8-版本中实现FreeMarker3.8+的!功能
2007-03-10 09:30 3470FreeMarker3.8中引入了一个非常实用的 ...
相关推荐
springMvc源码分析springMvc源码分析springMvc源码分析springMvc源码分析springMvc源码分析springMvc源码分析
springmvc源码流程解析
SpringMvc深入理解源码分析SpringMvc深入理解源码分析SpringMvc深入理解源码分析SpringMvc深入理解源码分析SpringMvc深入理解源码分析
SpringMvc主要流程源码解析(1).zip
对springMvc源码的深度解析,让大家更好的认识springMvc
SpringMvc 源码解析 包括DispatcherServlet初始化流程,拦截流程,处理逻辑等
springmvc深入解析.pdf
本篇文章主要介绍了SpringMVC源码解析之消息转换器HttpMessageConverter ,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
maven集成swagger与springMVC框架,只需导入到eclipse,启动maven即可运行。
Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动...支持本地化(Locale)解析、主题(Theme)解析及文件上传等;
SpringMVC-lean:看透SpringMVC源码分析与实战笔记
这个是自己仿照springmvc写的框架代码,不依赖于spring的任何框架,根据这个代码流程可以有效的理解springmvc源码。包括IOC容器的加载,url和controller的映射,注解的解析,页面模板的解析等等....
此中包含了大量的SpringMVC demo, 以及spring mvc 部分源码解析。
文档详细的解释了springmvc,有springmvc的配置及注解详解
Spring MVC源码深度剖析开源架构源码2021.pdf
看透SPRING MVC 源代码分析与实践
本文主要介绍了SpringMVC的源码解析。具有很好的参考价值,下面跟着小编一起来看下吧
spring
NULL 博文链接:https://zouruixin.iteye.com/blog/1441846
整合Spring +Spring MVC +Mybatis ,部署eclispe(maven) 可以直接运行