- 浏览: 756768 次
- 性别:
- 来自: 郑州
文章分类
- 全部博客 (396)
- JAVA (50)
- ORACLE (22)
- HIBERNATE (1)
- SPRING (26)
- STRUTS (4)
- OTHERS (0)
- MYSQL (11)
- Struts2 (16)
- JS (33)
- Tomcat (6)
- DWR (1)
- JQuery (26)
- JBoss (0)
- SQL SERVER (0)
- XML (10)
- 生活 (3)
- JSP (11)
- CSS (5)
- word (1)
- MyEclipse (7)
- JSTL (1)
- JEECMS (2)
- Freemarker (8)
- 页面特效 (1)
- EXT (2)
- Web前端 js库 (2)
- JSON http://www.json.org (3)
- 代码收集 (1)
- 电脑常识 (6)
- MD5加密 (0)
- Axis (0)
- Grails (1)
- 浏览器 (1)
- js调试工具 (1)
- WEB前端 (5)
- JDBC (2)
- PowerDesigner (1)
- OperaMasks (1)
- CMS (1)
- Java开源大全 (2)
- 分页 (28)
- Eclipse插件 (1)
- Proxool (1)
- Jad (1)
- Java反编译 (2)
- 报表 (6)
- JSON (14)
- FCKeditor (9)
- SVN (1)
- ACCESS (1)
- 正则表达式 (3)
- 数据库 (1)
- Flex (3)
- pinyin4j (2)
- IBATIS (3)
- probe (1)
- JSP & Servlet (1)
- 飞信 (0)
- AjaxSwing (0)
- AjaxSwing (0)
- Grid相关 (1)
- HTML (5)
- Guice (4)
- Warp framework (1)
- warp-persist (1)
- 服务器推送 (3)
- eclipse (1)
- JForum (5)
- 工具 (1)
- Python (1)
- Ruby (1)
- SVG (3)
- Joda-Time日期时间工具 (1)
- JDK (3)
- Pushlet (2)
- JSP & Servlet & FTP (1)
- FTP (6)
- 时间与效率 (4)
- 二维码 (1)
- 条码/二维码 (1)
最新评论
-
ctrlc:
你这是从web服务器上传到FTP服务器上的吧,能从用户电脑上上 ...
jsp 往 FTP 上传文件问题 -
annybz:
说的好抽象 为什么代码都有两遍。这个感觉没有第一篇 和第二篇 ...
Spring源代码解析(三):Spring JDBC -
annybz:
...
Spring源代码解析(一):IOC容器 -
jie_20:
你确定你有这样配置做过测试? 请不要转载一些自己没有测试的文档 ...
Spring2.0集成iReport报表技术概述 -
asd51731:
大哥,limit传-1时出错啊,怎么修改啊?
mysql limit 使用方法
上面我们分析了IOC容器本身的实现,下面我们看看在典型的web环境中,Spring IOC容器是怎样被载入和起作用的。
简单的说,
在web容器中,通过ServletContext为Spring的IOC容器提供宿主环境,对应的建立起一个IOC容器的体系。其中,首先需要建立的是
根上下文,这个上下文持有的对象可以有业务对象,数据存取对象,资源,事物管理器等各种中间层对象。在这个上下文的基础上,和web
MVC相关还会有一个上下文来保存控制器之类的MVC对象,这样就构成了一个层次化的上下文结构。在web容器中启动Spring应用程序就是一个建立这
个上下文体系的过程。Spring为web应用提供了上下文的扩展接口
WebApplicationContext:
- public interface WebApplicationContext extends ApplicationContext {
- //这里定义的常量用于在ServletContext中存取 根上下文
- String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext. class .getName() + ".ROOT" ;
- ......
- //对WebApplicationContext来说,需要 得到Web容器的ServletContext
- ServletContext getServletContext();
- }
public interface WebApplicationContext extends ApplicationContext { //这里定义的常量用于在ServletContext中存取根上下文 String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT"; ...... //对WebApplicationContext来说,需要得到Web容器的ServletContext ServletContext getServletContext(); }
而一般的启动过程,Spring会使用一个默认的实现,XmlWebApplicationContext -
这个上下文实现作为在web容器中的根上下文容器被建立起来,具体的建立过程在下面我们会详细分析。
- public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext {
- /** 这是和web部署相关的位置信息,用来作为默认的根上 下文bean定义信息的存放位置*/
- public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml" ;
- public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/" ;
- public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml" ;
- //我们又看到了熟悉的 loadBeanDefinition,就像我们前面对IOC容器的分析中一样,这个加载工程在容器的refresh()的时候启动。
- protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException {
- //对于 XmlWebApplicationContext,当然使用的是XmlBeanDefinitionReader来对bean定义信息来进行解析
- XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
- beanDefinitionReader.setResourceLoader( this );
- beanDefinitionReader.setEntityResolver( new ResourceEntityResolver( this ));
- initBeanDefinitionReader(beanDefinitionReader);
- loadBeanDefinitions(beanDefinitionReader);
- }
- protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) {
- }
- //使用XmlBeanDefinitionReader来读 入bean定义信息
- protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
- String[] configLocations = getConfigLocations();
- if (configLocations != null ) {
- for ( int i = 0 ; i < configLocations.length; i++) {
- reader.loadBeanDefinitions(configLocations[i]);
- }
- }
- }
- //这里取得bean定义信息位置,默认的地方是/WEB- INF/applicationContext.xml
- protected String[] getDefaultConfigLocations() {
- if (getNamespace() != null ) {
- return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX};
- }
- else {
- return new String[] {DEFAULT_CONFIG_LOCATION};
- }
- }
- }
public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext { /** 这是和web部署相关的位置信息,用来作为默认的根上下文bean定义信息的存放位置*/ public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml"; public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/"; public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml"; //我们又看到了熟悉的loadBeanDefinition,就像我们前面对IOC容器的分析中一样,这个加载工程在容器的refresh()的时候启动。 protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException { //对于XmlWebApplicationContext,当然使用的是XmlBeanDefinitionReader来对bean定义信息来进行解析 XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); initBeanDefinitionReader(beanDefinitionReader); loadBeanDefinitions(beanDefinitionReader); } protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) { } //使用XmlBeanDefinitionReader来读入bean定义信息 protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException { String[] configLocations = getConfigLocations(); if (configLocations != null) { for (int i = 0; i < configLocations.length; i++) { reader.loadBeanDefinitions(configLocations[i]); } } } //这里取得bean定义信息位置,默认的地方是/WEB-INF/applicationContext.xml protected String[] getDefaultConfigLocations() { if (getNamespace() != null) { return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX}; } else { return new String[] {DEFAULT_CONFIG_LOCATION}; } } }
对于一个Spring激活的web应用程序,可以通过使用Spring代码声明式的指定在web应用程序启动时载入应用程序上下文
(WebApplicationContext),Spring的ContextLoader是提供这样性能的类,我们可以使用
ContextLoaderServlet或者ContextLoaderListener的启动时载入的Servlet来实例化Spring
IOC容器 - 为什么会有两个不同的类来装载它呢,这是因为它们的使用需要区别不同的Servlet容器支持的Serlvet版本。但不管是
ContextLoaderSevlet还是
ContextLoaderListener都使用ContextLoader来完成实际的WebApplicationContext的初始化工作。这
个ContextLoder就像是Spring
Web应用程序在Web容器中的加载器booter。当然这些Servlet的具体使用我们都要借助web容器中的部署描述符来进行相关的定义。
下
面我们使用ContextLoaderListener作为载入器作一个详细的分析,这个Servlet的监听器是根上下文被载入的地方,也是整个
Spring web应用加载上下文的第一个地方;从加载过程我们可以看到,首先从Servlet事件中得到ServletContext,然后可以读到
配置好的在web.xml的中的各个属性值,然后ContextLoder实例化WebApplicationContext并完成其载入和初始化作为根
上下文。当这个根上下文被载入后,它被绑定到web应用程序的ServletContext上。任何需要访问该ApplicationContext的应
用程序代码都可以从WebApplicationContextUtils类的静态方法来得到:
WebApplicationContext getWebApplicationContext(ServletContext sc)
以Tomcat作为Servlet容器为例,下面是具体的步骤:
1.Tomcat
启动时需要从web.xml中读取启动参数,在web.xml中我们需要对ContextLoaderListener进行配置,对于在web应用启动入
口是在ContextLoaderListener中的初始化部分;从Spring
MVC上看,实际上在web容器中维护了一系列的IOC容器,其中在ContextLoader中载入的IOC容器作为根上下文而存在于
ServletContext中。
- //这里对根上下文进行初始化。
- public void contextInitialized(ServletContextEvent event) {
- //这里创建需要的ContextLoader
- this .contextLoader = createContextLoader();
- //这里使用ContextLoader对根上下文进行载入和 初始化
- this .contextLoader.initWebApplicationContext(event.getServletContext());
- }
//这里对根上下文进行初始化。 public void contextInitialized(ServletContextEvent event) { //这里创建需要的ContextLoader this.contextLoader = createContextLoader(); //这里使用ContextLoader对根上下文进行载入和初始化 this.contextLoader.initWebApplicationContext(event.getServletContext()); }
通过ContextLoader建立起根上下文的过程,我们可以在ContextLoader中看到:
- public WebApplicationContext initWebApplicationContext(ServletContext servletContext)
- throws IllegalStateException, BeansException {
- //这里先看看是不是已经在ServletContext中存 在上下文,如果有说明前面已经被载入过,或者是配置文件有错误。
- if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null ) {
- //直接抛出异常
- .........
- }
- ...............
- try {
- // 这里载入根上下文的父上下文
- ApplicationContext parent = loadParentContext(servletContext);
- //这里创建根上下文作为整个应用的上下文同时把它存 到ServletContext中去,注意这里使用的ServletContext的属性值是
- //ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, 以后的应用都是根据这个属性值来取得根上下文的 - 往往作为自己上下文的父上下文
- this .context = createWebApplicationContext(servletContext, parent);
- servletContext.setAttribute(
- WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this .context);
- ..........
- return this .context;
- }
- ............
- }
public WebApplicationContext initWebApplicationContext(ServletContext servletContext) throws IllegalStateException, BeansException { //这里先看看是不是已经在ServletContext中存在上下文,如果有说明前面已经被载入过,或者是配置文件有错误。 if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) { //直接抛出异常 ......... } ............... try { // 这里载入根上下文的父上下文 ApplicationContext parent = loadParentContext(servletContext); //这里创建根上下文作为整个应用的上下文同时把它存到ServletContext中去,注意这里使用的ServletContext的属性值是 //ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,以后的应用都是根据这个属性值来取得根上下文的 - 往往作为自己上下文的父上下文 this.context = createWebApplicationContext(servletContext, parent); servletContext.setAttribute( WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context); .......... return this.context; } ............ }
建立根上下文的父上下文使用的是下面的代码,取决于在web.xml中定义的参数:locatorFactorySelector,这是一
个可选参数:
- protected ApplicationContext loadParentContext(ServletContext servletContext)
- throws BeansException {
- ApplicationContext parentContext = null ;
- String locatorFactorySelector = servletContext.getInitParameter(LOCATOR_FACTORY_SELECTOR_PARAM);
- String parentContextKey = servletContext.getInitParameter(LOCATOR_FACTORY_KEY_PARAM);
- if (locatorFactorySelector != null ) {
- BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector);
- ........
- //得到根上下文的父上下文的引用
- this .parentContextRef = locator.useBeanFactory(parentContextKey);
- //这里建立得到根上下文的父上下文
- parentContext = (ApplicationContext) this .parentContextRef.getFactory();
- }
- return parentContext;
- }
protected ApplicationContext loadParentContext(ServletContext servletContext) throws BeansException { ApplicationContext parentContext = null; String locatorFactorySelector = servletContext.getInitParameter(LOCATOR_FACTORY_SELECTOR_PARAM); String parentContextKey = servletContext.getInitParameter(LOCATOR_FACTORY_KEY_PARAM); if (locatorFactorySelector != null) { BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector); ........ //得到根上下文的父上下文的引用 this.parentContextRef = locator.useBeanFactory(parentContextKey); //这里建立得到根上下文的父上下文 parentContext = (ApplicationContext) this.parentContextRef.getFactory(); } return parentContext; }
得到根上下文的父上下文以后,就是根上下文的创建过程:
- protected WebApplicationContext createWebApplicationContext(
- ServletContext servletContext, ApplicationContext parent) throws BeansException {
- //这里需要确定我们载入的根WebApplication的 类型,由在web.xml中配置的contextClass中配置的参数可以决定我们需要载入什么样的ApplicationContext,
- //如果没有使用默认的。
- Class contextClass = determineContextClass(servletContext);
- .........
- //这里就是上下文的创建过程
- ConfigurableWebApplicationContext wac =
- (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
- //这里保持对父上下文和ServletContext的引用 到根上下文中
- wac.setParent(parent);
- wac.setServletContext(servletContext);
- //这里从web.xml中取得相关的初始化参数
- String configLocation = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
- if (configLocation != null ) {
- wac.setConfigLocations(StringUtils.tokenizeToStringArray(configLocation,
- ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS));
- }
- //这里对WebApplicationContext进行初始 化,我们又看到了熟悉的refresh调用。
- wac.refresh();
- return wac;
- }
protected WebApplicationContext createWebApplicationContext( ServletContext servletContext, ApplicationContext parent) throws BeansException { //这里需要确定我们载入的根WebApplication的类型,由在web.xml中配置的contextClass中配置的参数可以决定我们需要载入什么样的ApplicationContext, //如果没有使用默认的。 Class contextClass = determineContextClass(servletContext); ......... //这里就是上下文的创建过程 ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass); //这里保持对父上下文和ServletContext的引用到根上下文中 wac.setParent(parent); wac.setServletContext(servletContext); //这里从web.xml中取得相关的初始化参数 String configLocation = servletContext.getInitParameter(CONFIG_LOCATION_PARAM); if (configLocation != null) { wac.setConfigLocations(StringUtils.tokenizeToStringArray(configLocation, ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS)); } //这里对WebApplicationContext进行初始化,我们又看到了熟悉的refresh调用。 wac.refresh(); return wac; }
初始化根ApplicationContext后将其存储到SevletContext中去以后,这样就建立了一个全局的关于整个应用的上
下文。这个根上下文会被以后的DispatcherServlet初始化自己的时候作为自己ApplicationContext的父上下文。这个在对
DispatcherServlet做分析的时候我们可以看看到。
3.完成对ContextLoaderListener的初始化以
后, Tomcat开始初始化DispatchServlet,-
还记得我们在web.xml中队载入次序进行了定义。DispatcherServlet会建立自己的ApplicationContext,同时建立这
个自己的上下文的时候会从ServletContext中得到根上下文作为父上下文,然后再对自己的上下文进行初始化,并最后存到
ServletContext中去供以后检索和使用。
可以从DispatchServlet的父类FrameworkServlet的代码中看
到大致的初始化过程,整个ApplicationContext的创建过程和ContextLoder创建的过程相类似:
- protected final void initServletBean() throws ServletException, BeansException {
- .........
- try {
- //这里是对上下文的初始化过程。
- this .webApplicationContext = initWebApplicationContext();
- //在完成对上下文的初始化过程结束后,根据bean 配置信息建立MVC框架的各个主要元素
- initFrameworkServlet();
- }
- ........
- }
protected final void initServletBean() throws ServletException, BeansException { ......... try { //这里是对上下文的初始化过程。 this.webApplicationContext = initWebApplicationContext(); //在完成对上下文的初始化过程结束后,根据bean配置信息建立MVC框架的各个主要元素 initFrameworkServlet(); } ........ }
对initWebApplicationContext()调用的代码如下:
- protected WebApplicationContext initWebApplicationContext() throws BeansException {
- //这里调用 WebApplicationContextUtils静态类来得到根上下文
- WebApplicationContext parent = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
- //创建当前DispatcherServlet的上下文,其 上下文种类使用默认的在FrameworkServlet定义好 的:DEFAULT_CONTEXT_CLASS = XmlWebApplicationContext.class;
- WebApplicationContext wac = createWebApplicationContext(parent);
- ........
- if (isPublishContext()) {
- //把当前建立的上下文存到 ServletContext中去,注意使用的属性名是和当前Servlet名相关的。
- String attrName = getServletContextAttributeName();
- getServletContext().setAttribute(attrName, wac);
- }
- return wac;
- }
protected WebApplicationContext initWebApplicationContext() throws BeansException { //这里调用WebApplicationContextUtils静态类来得到根上下文 WebApplicationContext parent = WebApplicationContextUtils.getWebApplicationContext(getServletContext()); //创建当前DispatcherServlet的上下文,其上下文种类使用默认的在FrameworkServlet定义好的:DEFAULT_CONTEXT_CLASS = XmlWebApplicationContext.class; WebApplicationContext wac = createWebApplicationContext(parent); ........ if (isPublishContext()) { //把当前建立的上下文存到ServletContext中去,注意使用的属性名是和当前Servlet名相关的。 String attrName = getServletContextAttributeName(); getServletContext().setAttribute(attrName, wac); } return wac; }
其中我们看到调用了WebApplicationContextUtils的静态方法得到根ApplicationContext:
- public static WebApplicationContext getWebApplicationContext(ServletContext sc) {
- //很简单,直接从ServletContext中通 过属性名得到根上下文
- Object attr = sc.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
- .......
- return (WebApplicationContext) attr;
- }
- 然后创建DispatcherServlet自己的WebApplicationContext:
- protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent)
- throws BeansException {
- .......
- //这里使用了BeanUtils直接得到 WebApplicationContext,ContextClass是前面定义好的 DEFAULT_CONTEXT_CLASS =
- //XmlWebApplicationContext.class;
- ConfigurableWebApplicationContext wac =
- (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(getContextClass());
- //这里配置父上下文,就是在 ContextLoader中建立的根上下文
- wac.setParent(parent);
- //保留ServletContext的引用和相关的 配置信息。
- wac.setServletContext(getServletContext());
- wac.setServletConfig(getServletConfig());
- wac.setNamespace(getNamespace());
- //这里得到ApplicationContext配 置文件的位置
- if (getContextConfigLocation() != null ) {
- wac.setConfigLocations(
- StringUtils.tokenizeToStringArray(
- getContextConfigLocation(), ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS));
- }
- //这里调用ApplicationContext的 初始化过程,同样需要使用refresh()
- wac.refresh();
- return wac;
- }
public static WebApplicationContext getWebApplicationContext(ServletContext sc) { //很简单,直接从ServletContext中通过属性名得到根上下文 Object attr = sc.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); ....... return (WebApplicationContext) attr; } 然后创建DispatcherServlet自己的WebApplicationContext: protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) throws BeansException { ....... //这里使用了BeanUtils直接得到WebApplicationContext,ContextClass是前面定义好的DEFAULT_CONTEXT_CLASS = //XmlWebApplicationContext.class; ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(getContextClass()); //这里配置父上下文,就是在ContextLoader中建立的根上下文 wac.setParent(parent); //保留ServletContext的引用和相关的配置信息。 wac.setServletContext(getServletContext()); wac.setServletConfig(getServletConfig()); wac.setNamespace(getNamespace()); //这里得到ApplicationContext配置文件的位置 if (getContextConfigLocation() != null) { wac.setConfigLocations( StringUtils.tokenizeToStringArray( getContextConfigLocation(), ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS)); } //这里调用ApplicationContext的初始化过程,同样需要使用refresh() wac.refresh(); return wac; }
4. 然后就是DispatchServlet中对Spring MVC的配置过程,首先对配置文件中的定义元素进行配置 -
请注意这个时候我们的WebApplicationContext已经建立起来了,也意味着DispatcherServlet有自己的定义资源,可以需
要从web.xml中读取bean的配置信息,通常我们会使用单独的xml文件来配置MVC中各个要素定义,这里和web容器相关的加载过程实际上已经完
成了,下面的处理和普通的Spring应用程序的编写没有什么太大的差别,我们先看看MVC的初始化过程:
- protected void initFrameworkServlet() throws ServletException, BeansException {
- initMultipartResolver();
- initLocaleResolver();
- initThemeResolver();
- initHandlerMappings();
- initHandlerAdapters();
- initHandlerExceptionResolvers();
- initRequestToViewNameTranslator();
- initViewResolvers();
- }
protected void initFrameworkServlet() throws ServletException, BeansException { initMultipartResolver(); initLocaleResolver(); initThemeResolver(); initHandlerMappings(); initHandlerAdapters(); initHandlerExceptionResolvers(); initRequestToViewNameTranslator(); initViewResolvers(); }
5. 这样MVC的框架就建立起来了,DispatchServlet对接受到的HTTP
Request进行分发处理由doService()完成,具体的MVC处理过程我们在doDispatch()中完成,其中包括使用Command模式
建立执行链,显示模型数据等,这些处理我们都可以在DispatcherServlet的代码中看到:
- protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
- ......
- try {
- doDispatch(request, response);
- }
- .......
- }
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception { ...... try { doDispatch(request, response); } ....... }
实际的请求分发由doDispatch(request,response)来完成:
- protected void doDispatch( final HttpServletRequest request, HttpServletResponse response) throws Exception {
- .......
- // 这是Spring定义的执行链,里面放了映射关系对应 的handler和定义的相关拦截器。
- HandlerExecutionChain mappedHandler = null ;
- ......
- try {
- //我们熟悉的ModelAndView在这里出 现了。
- ModelAndView mv = null ;
- try {
- processedRequest = checkMultipart(request);
- //这里更具request中的参数和映 射关系定义决定使用的handler
- mappedHandler = getHandler(processedRequest, false );
- ......
- //这里是handler的调用过程,类 似于Command模式中的execute.
- HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
- mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
- .......
- //这里将模型数据通过视图进行展现
- if (mv != null && !mv.wasCleared()) {
- render(mv, processedRequest, response);
- }
- ........
- }
protected void doDispatch(final HttpServletRequest request, HttpServletResponse response) throws Exception { ....... // 这是Spring定义的执行链,里面放了映射关系对应的handler和定义的相关拦截器。 HandlerExecutionChain mappedHandler = null; ...... try { //我们熟悉的ModelAndView在这里出现了。 ModelAndView mv = null; try { processedRequest = checkMultipart(request); //这里更具request中的参数和映射关系定义决定使用的handler mappedHandler = getHandler(processedRequest, false); ...... //这里是handler的调用过程,类似于Command模式中的execute. HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); ....... //这里将模型数据通过视图进行展现 if (mv != null && !mv.wasCleared()) { render(mv, processedRequest, response); } ........ }
这样具体的MVC模型的实现就由bean配置文件里定义好的view resolver,handler这些类来实现用户代码的功能。
总
结上面的过程,我们看到在web容器中,ServletContext可以持有一系列的web上下文,而在整个web上下文中存在一个根上下文来作为其它
Servlet上下文的父上下文。这个根上下文是由ContextLoader载入并进行初始化的,对于我们的web应用,
DispatcherSerlvet载入并初始化自己的上下文,这个上下文的父上下文是根上下文,并且我们也能从ServletContext中根据
Servlet的名字来检索到我们需要的对应于这个Servlet的上下文,但是根上下文的名字是由Spring唯一确定的。这个
DispactcherServlet建立的上下文就是我们开发Spring MVC应用的IOC容器。
具体的web请求处理在上下文体系建立
完成以后由DispactcherServlet来完成,上面对MVC的运作做了一个大致的描述,下面我们会具体就SpringMVC的框架实现作一个详
细的分析。
发表评论
-
Spring--quartz中cronExpression配置说明
2011-12-02 18:28 0quartz中cronExpression配置说明 字段 ... -
使用Spring的jdbcTemplate进一步简化JDBC操作
2011-12-02 09:20 1268先看applicationContext.xml配置文件: ... -
Spring MVC:使用SimpleUrlHandlerMapping的一个简单例子
2011-12-01 11:26 969实现一个控制器ShirdrnCon ... -
最简单的Spring MVC入门示例
2010-05-19 14:29 1532应一位朋友的要求,写一个最简单的spring示例,使用s ... -
Spring源代码解析(十):Spring Acegi框架授权的实现
2010-03-18 12:48 1527我们从FilterSecurityIntercep ... -
Spring源代码解析(九):Spring Acegi框架鉴权的实现
2010-03-18 12:47 1512简单分析一下Spring Acegi的源代码实现: Ser ... -
Spring源代码解析(八):Spring驱动Hibernate的实现
2010-03-18 12:41 1454O/R工具出现之后,简化了许多复杂的信息持久化的开发。Spri ... -
Spring源代码解析(七):Spring AOP中对拦截器调用的实现
2010-03-18 12:40 1425前面我们分析了Spring AOP实现中得到Proxy对象的过 ... -
Spring源代码解析(六):Spring声明式事务处理
2010-03-18 12:37 1105我们看看Spring中的事务处理的代码,使用Spring管理事 ... -
Spring源代码解析(五):Spring AOP获取Proxy
2010-03-18 12:36 1327下面我们来看看Spring的AOP的一些相关代码是怎么得到Pr ... -
Spring源代码解析(四):Spring MVC
2010-03-18 12:35 7750下面我们对Spring MVC框架代码进行分析,对于web ... -
Spring源代码解析(三):Spring JDBC
2010-03-18 12:33 1702下面我们看看Spring JDBC相关的实现, 在Spri ... -
Spring源代码解析(一):IOC容器
2010-03-18 12:30 2677在Spring中,IOC容器的重要地位我们就不多说了,对于Sp ... -
使用Spring的JdbcTemplate和BeanPropertyRowMapper完成的JDBC
2010-03-18 12:08 2250先道要加上两个包:Spring2.5下面的: spring. ... -
使用Spring的SimpleJdbcTemplate完成DAO操作
2010-03-18 12:06 1513l SimpleJdbcTemplate内部包含了 ... -
使用Spring的NamedParameterJdbcTemplate完成DAO操作
2010-03-18 12:05 1435NamedParameterJdbcTemplate内部包含了 ... -
Spring in Action 学习笔记—第四章 征服数据库(转)
2010-03-18 12:03 1258Spring2.0正式版(http://www.springf ... -
Spring管理JDBC连接
2010-03-18 11:59 1696在Spring中,JdbcTemplate是经常被使用的类来帮 ... -
Spring JDBC数据库操作类
2010-03-18 09:26 16491.JdbcTemplate 在Spring中, ... -
Spring JdbcTemplate 批量插入或更新操作
2010-03-18 09:19 5288用 JdbcTemplate 进行批量插入或更新操作 ...
相关推荐
在Spring源代码解析的第一部分,我们将聚焦于IOC容器,特别是BeanFactory接口,它是所有Spring容器的基础。 BeanFactory接口是Spring的基石,它定义了基本的容器操作,如获取Bean、检查Bean是否存在、确定Bean的...
Spring源代码解析2:IoC容器在Web容器中的启动.doc Spring源代码解析3:Spring JDBC .doc Spring源代码解析4:Spring MVC .doc Spring源代码解析5:Spring AOP获取Proxy .doc Spring源代码解析6:Spring声明式事务...
Spring源代码解析2:IoC容器在Web容器中的启动;Spring源代码解析3:Spring JDBC ; Spring源代码解析4:Spring MVC ;Spring源代码解析5:Spring AOP获取Proxy;Spring源代码解析6:Spring声明式事务处理 ; ...
当我们在Web环境中运行Spring应用时,IoC容器需要在Web容器(如Tomcat、Jetty等)中启动并运行。这个过程涉及到一系列的初始化步骤,确保Spring能够正确地与Web容器集成。 首先,`WebApplicationContext`是`...
Spring源代码解析(二):IoC容器在Web容器中的启动 Spring源代码解析(三):Spring JDBC Spring源代码解析(四):Spring MVC Spring源代码解析(五):Spring AOP获取Proxy Spring源代码解析(六):Spring声明式事务...
Spring源代码解析2:IoC容器在Web容器中的启动;Spring源代码解析3:Spring JDBC ; Spring源代码解析4:Spring MVC ;Spring源代码解析5:Spring AOP获取Proxy;Spring源代码解析6:Spring声明式事务处理 ; ...
2. **Web环境下的IOC容器启动**:"spring源代码解析(二):IOC容器在web中启动.doc"涵盖了在Web应用中初始化Spring容器的过程,包括ApplicationContext的创建、DispatcherServlet的配置以及如何在Web环境中注入bean...
Spring源代码解析(二):ioc容器在Web容器中的启动.doc Spring源代码分析(三):Spring JDBC.doc Spring源代码解析(四):Spring MVC.doc Spring源代码解析(五):Spring AOP获取Proxy.doc Spring源代码解析(六):...
《Spring源代码解析》 Spring框架作为Java领域最流行的开源框架之一,它的设计思想和实现方式一直是广大开发者关注的焦点。深入理解Spring的源代码,能够帮助我们更好地掌握其工作原理,提高我们的开发效率和代码...
这个“Spring源代码解析”压缩包文件很可能是对Spring框架内部实现原理的详细分析,帮助开发者深入理解其工作机制。 在Spring框架中,依赖注入是核心概念之一,它允许开发者在运行时通过容器来管理对象的创建和依赖...
源代码分析有助于深入理解Spring的工作原理,提升编程技能,并且能够帮助开发者在遇到问题时进行调试和优化。 1. **Spring IoC容器**: Spring的核心是IoC容器,它负责管理对象的生命周期和依赖关系。通过XML配置...
《精通Spring源代码》是罗时飞先生关于Spring框架深入解析的一部著作,旨在帮助开发者更深入地理解Spring的工作原理,提升对Java企业级应用开发的掌控能力。本压缩包包含的文件名为“精通Spring源码”,这通常是一个...
在`spring-framework-master`这个压缩包中,包含了Spring框架的完整源代码。开发者可以深入研究以下几个关键部分: - `spring-beans`:包含IoC容器的实现。 - `spring-core`:基础核心工具类,提供反射、资源加载等...
Spring如何在Web环境中集成IoC容器并为Web应用开发提供利器? 我们耳熟能详的MVC模式在Spring中是如何实现的? Spring MVC如何灵活地集成各种丰富的视图展现方案? Spring实现远端调用的方案有很多种,你...
在描述中提到的"Spring源代码的下载地址",通常是指Spring官方仓库或者第三方镜像站点。Spring的源代码托管在GitHub上,你可以访问Spring官方网站(https://spring.io/)找到链接,或者直接前往GitHub...