- 浏览: 1249834 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (193)
- ant/maven (6)
- algorithm (5)
- tomcat/weblogic/jboss (6)
- javascript/jquery (13)
- java (33)
- flex/flash (0)
- JPA/Hibernate/myBatis (18)
- java concurrent (7)
- test (2)
- windows/linux (6)
- java collection (7)
- design pattern (2)
- life/health (3)
- database (12)
- IDE (4)
- spring/ejb (20)
- html/css/ckeditor (7)
- jsp/servlet (3)
- java io (13)
- java security (4)
- jni (0)
- svn/git (2)
- english (2)
- java jmx (1)
- xml (1)
- struts/springmvc (9)
- middleware (2)
- cache (1)
- cglib (3)
最新评论
-
jlotusYo:
博主,真感谢。
Java 密码扩展无限制权限策略文件 -
senninha:
这个。。是api说明吧。。
ScheduledExecutorService 源码分析 -
zoutao2008:
请问大文件如何处理?按你这种方式的话,文件超过200M时就会报 ...
hessian系列之二:上传文件 -
lwj1113:
lwj1113 写道谢谢博主这么细致的demo;在系列五中通过 ...
myBatis系列之五:与Spring3集成 -
lwj1113:
谢谢博主这么细致的demo;在系列五中通过testng测试类跑 ...
myBatis系列之五:与Spring3集成
1. 继承结构:
HttpServletBean把普通的Servlet包装成Spring的bean,这样可以将init-param的值作为bean的属性注入。
FrameworkServlet完成了Spring的容器(WebApplicationContext)的初始化工作,关键方法是initWebApplicationContext()方法,并放到Servlet对象之中。
2. 初始化组件
用户没有配置组件时,将使用预定义的值。这里以HandlerMappings为例,其它组件的初始化类似:
3. 处理请求
请求到达,容器调用DispatcherServlet的service()方法,最终会调用doDispatcher()方法:
附:DispatcherServlet.properties
HttpServletBean把普通的Servlet包装成Spring的bean,这样可以将init-param的值作为bean的属性注入。
FrameworkServlet完成了Spring的容器(WebApplicationContext)的初始化工作,关键方法是initWebApplicationContext()方法,并放到Servlet对象之中。
2. 初始化组件
用户没有配置组件时,将使用预定义的值。这里以HandlerMappings为例,其它组件的初始化类似:
// 初始化 private void initHandlerMappings(ApplicationContext context) { this.handlerMappings = null; if (this.detectAllHandlerMappings) { // Find all HandlerMappings in the ApplicationContext, including ancestor contexts. Map<String, HandlerMapping> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false); if (!matchingBeans.isEmpty()) { this.handlerMappings = new ArrayList<HandlerMapping>(matchingBeans.values()); OrderComparator.sort(this.handlerMappings); // 排序 } } else { try { HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class); // 从上下文中获取名称为handlerMapping的映射处理器 this.handlerMappings = Collections.singletonList(hm); } catch (NoSuchBeanDefinitionException ex) { // Ignore, we'll add a default HandlerMapping later. } } // 确保至少有一个映射处理器 // 如果没有其它的映射处理器,预定义的(从DispatcherServlet.properties读取)将被实例化。 if (this.handlerMappings == null) { this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class); if (logger.isDebugEnabled()) { logger.debug("No HandlerMappings found in servlet '" + getServletName() + "': using default"); } } }
private static final String DEFAULT_STRATEGIES_PATH = "DispatcherServlet.properties"; static { // 从属性文件加载默认组件实现。 // 内部的实现,不意味着被外部修改。 try { ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class); defaultStrategies = PropertiesLoaderUtils.loadProperties(resource); } catch (IOException ex) { throw new IllegalStateException("Could not load 'DispatcherServlet.properties': " + ex.getMessage()); } }
protected <T> List<T> getDefaultStrategies(ApplicationContext context, Class<T> strategyInterface) { String key = strategyInterface.getName(); String value = defaultStrategies.getProperty(key); if (value != null) { String[] classNames = StringUtils.commaDelimitedListToStringArray(value); List<T> strategies = new ArrayList<T>(classNames.length); for (String className : classNames) { try { Class<?> clazz = ClassUtils.forName(className, DispatcherServlet.class.getClassLoader()); Object strategy = createDefaultStrategy(context, clazz); strategies.add((T) strategy); } catch (ClassNotFoundException ex) { throw new BeanInitializationException( "Could not find DispatcherServlet's default strategy class [" + className + "] for interface [" + key + "]", ex); } catch (LinkageError err) { throw new BeanInitializationException( "Error loading DispatcherServlet's default strategy class [" + className + "] for interface [" + key + "]: problem with class file or dependent class", err); } } return strategies; } else { return new LinkedList<T>(); } } protected <T> T getDefaultStrategy(ApplicationContext context, Class<T> strategyInterface) { List<T> strategies = getDefaultStrategies(context, strategyInterface); if (strategies.size() != 1) { throw new BeanInitializationException( "DispatcherServlet needs exactly 1 strategy for interface [" + strategyInterface.getName() + "]"); } return strategies.get(0); }
3. 处理请求
请求到达,容器调用DispatcherServlet的service()方法,最终会调用doDispatcher()方法:
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { HttpServletRequest processedRequest = request; HandlerExecutionChain mappedHandler = null; int interceptorIndex = -1; try { ModelAndView mv; boolean errorView = false; try { processedRequest = checkMultipart(request); // 检查是否multipart的请求 // 找到匹配当前请求的映射处理器。 mappedHandler = getHandler(processedRequest, false); if (mappedHandler == null || mappedHandler.getHandler() == null) { noHandlerFound(processedRequest, response); return; } // 找到匹配的处理适配器。 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // 如果处理器支持,处理last-modified头. String method = request.getMethod(); boolean isGet = "GET".equals(method); if (isGet || "HEAD".equals(method)) { long lastModified = ha.getLastModified(request, mappedHandler.getHandler()); if (logger.isDebugEnabled()) { String requestUri = urlPathHelper.getRequestUri(request); logger.debug("Last-Modified value for [" + requestUri + "] is: " + lastModified); } if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) { return; } // 如果是GET请求且资源自上次修改时间起未被修改 } // 调用已注册拦截器的preHandle方法。 HandlerInterceptor[] interceptors = mappedHandler.getInterceptors(); if (interceptors != null) { for (int i = 0; i < interceptors.length; i++) { HandlerInterceptor interceptor = interceptors[i]; if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) { // 调用preHandle失败 triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null); // 进行完成后的处理操作 return; } interceptorIndex = i; // 记录调用成功的拦截器的索引。 } } // 调用处理器的方法。 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); // 如果视图没有指定,根据请求生成默认视图 if (mv != null && !mv.hasView()) { mv.setViewName(getDefaultViewName(request)); } // 逆序调用已注册拦截器的postHandle方法。 if (interceptors != null) { for (int i = interceptors.length - 1; i >= 0; i--) { HandlerInterceptor interceptor = interceptors[i]; interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv); } } } catch (ModelAndViewDefiningException ex) { logger.debug("ModelAndViewDefiningException encountered", ex); mv = ex.getModelAndView(); } catch (Exception ex) { Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null); mv = processHandlerException(processedRequest, response, handler, ex); errorView = (mv != null); } // 处理器返回视图? if (mv != null && !mv.wasCleared()) { render(mv, processedRequest, response); // 使用数据渲染视图 if (errorView) { WebUtils.clearErrorRequestAttributes(request); } } else { if (logger.isDebugEnabled()) { logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() + "': assuming HandlerAdapter completed request handling"); } } // 从调用成功拦截器的索引开始,逆序调用完成后的处理。 triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null); } catch (Exception ex) { // 异常,手动调用完成后的处理。 triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex); throw ex; } catch (Error err) { ServletException ex = new NestedServletException("Handler processing failed", err); // 错误,手动调用完成后的处理。 triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex); throw ex; } finally { // 清理被multipart请求占用的资源。 if (processedRequest != request) { cleanupMultipart(processedRequest); } } }
附:DispatcherServlet.properties
# Default implementation classes for DispatcherServlet's strategy interfaces. # Used as fallback when no matching beans are found in the DispatcherServlet context. # Not meant to be customized by application developers. org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\ org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\ org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\ org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\ org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\ org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager
发表评论
-
Struts2系列之四:导出文件重复头问题
2014-12-02 21:44 0Struts 2的result有很多种类型,从struts2- ... -
Struts2系列之三:注解式Action
2014-10-08 23:18 6188struts2是的配置文件 ... -
SpringMVC系列之三:集成Log4j
2013-12-20 15:42 7317SpringMVC系列之一、集成JSP SpringMVC系列 ... -
FreeMarker 加载模板和填充数据
2013-10-26 22:21 0一、加载模板: a. 初始化模板加载器: b ... -
SpringMVC系列之二、集成FreeMarker
2013-10-26 22:55 4203SpringMVC系列之一、集成JSP SpringMVC系列 ... -
SpringMVC系列之一、集成JSP
2013-10-16 16:59 1932SpringMVC系列之一、集成JSP SpringMVC系列 ... -
配置struts1项目
2012-12-26 23:35 16621. 打开IDE(如Eclipse),新建一个Web Proj ... -
struts1 国际化资源文件
2012-11-24 14:50 22161. 名称规范: 引用[Name].properties / ... -
Struts2系列之二:页面传值
2013-11-29 18:19 5544Struts2系列之一:构建struts2项目 Struts2 ... -
struts2的配置
2012-05-04 20:35 01. 这里的后缀如果加上jsp,那么后缀名为jsp的请求都将交 ... -
Struts2系列之一:构建struts2项目
2012-04-26 20:27 1681Struts2系列之二:页面传值 Struts2系列之三:注解 ...
相关推荐
Spring源码学习九:DispatcherServlet初始化源码分析1 DispatcherServlet是SpringMVC的核心分发器,它实现了请求分发,是处理请求的入口,本篇将深入源码分析它的初始化过程。 首先,从DispatcherServlet的名称上...
源码分析会涉及SpringBoot的启动流程,包括`SpringApplication.run()`方法的执行细节,自动配置的实现机制,以及如何通过条件注解选择合适的bean。理解这些将帮助你自定义启动配置,优化项目结构。 接着,进入...
本篇文章将深入探讨DispatcherServlet的请求分发流程。 DispatcherServlet继承自HttpServlet,其核心功能在于处理HTTP请求。在Servlet的service方法中,DispatcherServlet会接收到请求并进行分发。在...
DispatcherServlet是核心组件,它负责请求分发。Controller接口定义了处理请求的方法,视图解析器将Model数据渲染成视图,ModelAndView类则用于封装处理结果。 5. **Spring AOP**:AOP(Aspect Oriented ...
在IT行业中,源码分析是理解框架工作原理和优化应用的关键步骤。以下是对标题和描述中提到的几个关键组件——Ribbon、Feign、Dubbo、Sentinel的源码分析,以及与它们相关的Spring Boot启动过程、配置文件加载流程、...
Java框架源码分析是软件开发领域中的重要环节,它能帮助开发者深入理解框架的工作原理,提升编程技巧,优化代码质量,以及解决实际开发中的问题。本文将围绕Java框架的源码分析进行详细探讨。 首先,Java框架是为...
在这个源码分析中,我们将深入探讨Spring MVC的核心组件和工作流程。 1. **DispatcherServlet**:Spring MVC的入口点,它是所有请求的前端控制器。当一个HTTP请求到达服务器时,DispatcherServlet负责拦截请求,并...
《Spring5 源码分析(第 2 版)》是某Tom老师精心编写的深度解析文档,旨在帮助读者全面理解Spring5的核心机制和设计理念。Spring作为Java领域最为广泛应用的框架之一,其源码的深入理解对于开发者来说至关重要。这篇...
在深入探讨Spring源码分析流程之前,我们先要理解Spring框架的基本概念。Spring是一个轻量级的Java企业级应用框架,它提供了丰富的功能,包括依赖注入(DI)、面向切面编程(AOP)、数据访问、事务管理等。Spring的...
SpringBoot是一个基于Spring框架的高度模块化和...以上就是SpringBoot请求处理的源码分析,涉及的主要组件和它们的角色。理解这些组件的工作原理有助于开发者深入理解SpringBoot的请求处理流程,提高开发和调试的效率。
《Spring高级源码分析》是针对Java开发人员深入理解Spring框架的一份宝贵资源。Spring作为Java企业级应用的基石,其强大的功能和灵活性源于其深厚的设计理念和精巧的源码实现。本分析将深入探讨Spring的核心机制,...
#### 四、深入源码分析:`DispatcherServlet` 接下来,我们将深入分析`DispatcherServlet`的一些关键部分。 1. **DispatcherServlet继承关系**: - `DispatcherServlet`继承自`FrameworkServlet`,而`...
《Spring源码分析》 Spring框架作为Java领域最流行的开源框架之一,它的设计思想和实现方式一直是许多开发者深入研究的对象。这份"Spring源码分析"资料深入探讨了Spring的核心机制,帮助我们理解其背后的原理,从而...
在"SpringMVC_源码分析代码.zip"这个压缩包中,我们可以找到一个名为"5.SpringMVC_output"的文件或目录,这可能包含的是一个示例项目的结果输出,或者是源码分析过程中的测试或运行产出。通常,这样的文件夹会包括...
Struts源码分析: 1. **ActionServlet**:Struts的核心控制器,负责接收HTTP请求,解析请求参数,并调用相应的Action来处理业务逻辑。 2. **ActionMapping**:用于映射请求URL到特定的Action,它包含了Action的配置...
下面我们将深入探讨Struts 1的源码分析,特别是针对Struts 1.2版本。 1. **架构概述** - **DispatcherServlet**:作为Struts的核心,DispatcherServlet负责接收HTTP请求并分发到相应的Action。 - **ActionMapping...
本视频课程“SpringMvc深入理解源码分析”旨在帮助开发者深入理解Spring MVC的工作原理和核心机制,从而更好地利用它来构建高效、可维护的Web应用。 在Spring MVC中,主要涉及以下几个核心概念: 1. **...