- 浏览: 1239740 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (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 6123struts2是的配置文件 ... -
SpringMVC系列之三:集成Log4j
2013-12-20 15:42 7269SpringMVC系列之一、集成JSP SpringMVC系列 ... -
FreeMarker 加载模板和填充数据
2013-10-26 22:21 0一、加载模板: a. 初始化模板加载器: b ... -
SpringMVC系列之二、集成FreeMarker
2013-10-26 22:55 4156SpringMVC系列之一、集成JSP SpringMVC系列 ... -
SpringMVC系列之一、集成JSP
2013-10-16 16:59 1884SpringMVC系列之一、集成JSP SpringMVC系列 ... -
配置struts1项目
2012-12-26 23:35 16321. 打开IDE(如Eclipse),新建一个Web Proj ... -
struts1 国际化资源文件
2012-11-24 14:50 21831. 名称规范: 引用[Name].properties / ... -
Struts2系列之二:页面传值
2013-11-29 18:19 5487Struts2系列之一:构建struts2项目 Struts2 ... -
struts2的配置
2012-05-04 20:35 01. 这里的后缀如果加上jsp,那么后缀名为jsp的请求都将交 ... -
Struts2系列之一:构建struts2项目
2012-04-26 20:27 1644Struts2系列之二:页面传值 Struts2系列之三:注解 ...
相关推荐
Spring源码学习九:DispatcherServlet初始化源码分析1
总结:首先,SpringMVC框架在启动的时候会遍历Spring容器中的所有bean,对标注了@Controller或并,使用@RequestMapping注解
Spring的源码分析 在分析SpringMVC源码之前我想先回顾一下JavaWeb的知识.JavaWeb的核心是Servlet,一个Servlet对应一个URL, 每次一个Http请求访问,那么对应URL的Servlet就会调用service方法处理。 其实这里我是对...
关于spring中的注解,采用和spring一样的注解名字,在springMVC方面,采用统一的前端控制器dispatcherServlet,处理统一请求进行分发。 对应 mybatis 是采用代理的方式 对接口进行生成对应的代理对象,加载对应的xml...
spring mvc的版本是5.x的,sping mvc的入口是 DispatcherServlet 类 ,在之前的ssm项目中,我们是通过配置在web.xml中的servlet把请求的入口设置为DispatcherServlet,现在的版本官方不提倡编写web.xml,而是如下: ...
xml java系统源码 源码DEBUG专用工程。 微信搜索:'菜鸟封神记'公众号,定期分享Spring源码系列...主要提供对SpringMVC的支持,例如SpringMVC中的DispatcherServlet就是该模块中提供的; spring-websocket: 提供对We
java进阶源码分析专题常用设计模式线程与并发锁的使用深度理解synchronized、volatile、cas手写ASQSpring5IOC容器设计原理及高级特性AOP设计原理FactoryBean与BeanFactorySpring事务处理机制Spring JDK动态代理...
10.3.4 建立Spring的配置文档dispatcherServlet-servlet.xml 10.3.5 配置web.xml 10.3.6 启动Tomcat运行程序 10.4 Spring 的视图(View) 10.4.1 视图简介 10.4.2 视图解析 10.5 Spring的控制器(Controller) ...
一共四个,其中pdf 三个包,源码一个包 第一章 J2EE快速入门 1.1 J2EE概述 1.1.1 J2EE的来源 1.1.2 J2EE整体框架 1.1.3 从J2EE到JavaEE 1.2 J2EE组件 1.2.1 客户端组件 1.2.2 Web组件 1.2.3 业务逻辑组件 1.3 J2EE...
一共四个,其中pdf 三个包,源码一个包 第一章 J2EE快速入门 1.1 J2EE概述 1.1.1 J2EE的来源 1.1.2 J2EE整体框架 1.1.3 从J2EE到JavaEE 1.2 J2EE组件 1.2.1 客户端组件 1.2.2 Web组件 1.2.3 业务逻辑组件 1.3 J2EE...
一共四个,其中pdf 三个包,源码一个包 第一章 J2EE快速入门 1.1 J2EE概述 1.1.1 J2EE的来源 1.1.2 J2EE整体框架 1.1.3 从J2EE到JavaEE 1.2 J2EE组件 1.2.1 客户端组件 1.2.2 Web组件 1.2.3 业务逻辑组件 1.3 J2EE...