`
sha0k
  • 浏览: 84893 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

Spring MVC 源码学习札记(二)ViewResolver处理viewname

 
阅读更多

第一节我们看到了ViewResolver对ModelAndView中属性Oject view为String时,将调用方法:

	protected View resolveViewName(String viewName, Map<String, Object> model, Locale locale,
			HttpServletRequest request) throws Exception {

		for (ViewResolver viewResolver : this.viewResolvers) {
			View view = viewResolver.resolveViewName(viewName, locale);
			if (view != null) {
				return view;
			}
		}
		return null;
	}

 所以这一节就来了解下resolveViewName的机制。

来看看我们第一眼能懂的,Internal产生的是JstlView,Freemarker不用说,Velocity不用说,那就从这三个类来入手。

还是过程式的代码阅读,我们去找resovlveViewName 这个方法。

在AbstractCachingViewResolver类中:

 

public View resolveViewName(String viewName, Locale locale) throws Exception {
		if (!isCache()) {
			return createView(viewName, locale);



		}
		else {
			Object cacheKey = getCacheKey(viewName, locale);
			synchronized (this.viewCache) {
				View view = this.viewCache.get(cacheKey);
				if (view == null) {
					// Ask the subclass to create the View object.
					view = createView(viewName, locale);
					this.viewCache.put(cacheKey, view);
					if (logger.isTraceEnabled()) {
						logger.trace("Cached view [" + cacheKey + "]");
					}
				}
				return view;
			}
		}
	}

 

protected View createView(String viewName, Locale locale) throws Exception {
		return loadView(viewName, locale);



	}
 
protected abstract View loadView(String viewName, Locale locale) throws Exception;//子类必须实现这个方法
 

  loadView方法又将我们带入了AbstractCachingViewResolver的子类UrlBasedViewResolver类中,可以发现UrlBasedViewResolver类中:

 

/**
	 * Overridden to implement check for "redirect:" prefix.
	 * <p>Not possible in <code>loadView</code>, since overridden
	 * <code>loadView</code> versions in subclasses might rely on the
	 * superclass always creating instances of the required view class.
	 * @see #loadView
	 * @see #requiredViewClass
	 */
	@Override
	protected View createView(String viewName, Locale locale) throws Exception {
		// If this resolver is not supposed to handle the given view,
		// return null to pass on to the next resolver in the chain.
		if (!canHandle(viewName, locale)) {
			return null;
		}
		// Check for special "redirect:" prefix.
		if (viewName.startsWith(REDIRECT_URL_PREFIX)) {
			String redirectUrl = viewName.substring(REDIRECT_URL_PREFIX.length());
			return new RedirectView(redirectUrl, isRedirectContextRelative(), isRedirectHttp10Compatible());
		}
		// Check for special "forward:" prefix.
		if (viewName.startsWith(FORWARD_URL_PREFIX)) {
			String forwardUrl = viewName.substring(FORWARD_URL_PREFIX.length());
			return new InternalResourceView(forwardUrl);
		}
		// Else fall back to superclass implementation: calling loadView.
		return super.createView(viewName, locale);
	}

 这里千万别糊涂哦,这可是java基础知识多态哦。。。。

 因为在DispatcherServlet中的viewResolvers保存的都是ViewResolver的实现类的对象,那么调用接口的resolveViewName方法后,就得一层层来看这个方法了,从代码中我们看到的是只有AbstractCachingViewResolver有这个方法,那肯定调用的是它的。但是在resolveViewName中又调用了createView,那么这里调用的就是UrlBasedViewResolver的方法了。

 

所以在该方法前面的if都没得到满足时,才去显示的调用父类的createView方法。

// Else fall back to superclass implementation: calling loadView.
		return super.createView(viewName, locale);

 

这时父类的createView调用了loadView方法,而UrlBasedViewResolver又实现了这一方法,自然而然是调用它的loadView方法,而Internal暴露了buildView方法,则loadView执行时首先调用Internal的buildView。

@Override
	protected View loadView(String viewName, Locale locale) throws Exception {
		AbstractUrlBasedView view = buildView(viewName);
		View result = (View) getApplicationContext().getAutowireCapableBeanFactory().initializeBean(view, viewName);
		return (view.checkResource(locale) ? result : null);
	}

 UrlBasedViewResolver类中的buildView方法

 

protected AbstractUrlBasedView buildView(String viewName) throws Exception {
		AbstractUrlBasedView view = (AbstractUrlBasedView) BeanUtils.instantiateClass(getViewClass());
		view.setUrl(getPrefix() + viewName + getSuffix());
		String contentType = getContentType();
		if (contentType != null) {
			view.setContentType(contentType);
		}
		view.setRequestContextAttribute(getRequestContextAttribute());
		view.setAttributesMap(getAttributesMap());
		return view;
	}

  InternalResourceViewResolver的buildView方法,忽然看到这个viewClass让我眼前一亮,终于知道Freemarker去生成静态页面是怎么做到的了,用自己实现的类配置在Resolver的属性中,这样等于是做了一次拦截。

<bean id="freemarkerViewResolver"
		class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
		<property name="contentType" value="text/html;charset=gbk" />
		<property name="viewClass" value="com.sha0k.util.MyFreeMarkerView">
		</property>
		<property name="exposeRequestAttributes">
			<value>true</value>
		</property>
		<property name="exposeSessionAttributes">
			<value>true</value>
		</property>
		<property name="order">
			<value>1</value>
		</property>
		<property name="suffix" value=".ftl" />
	</bean>
 

 

@Override
	protected AbstractUrlBasedView buildView(String viewName) throws Exception {
		InternalResourceView view = (InternalResourceView) super.buildView(viewName);
		if (this.alwaysInclude != null) {
			view.setAlwaysInclude(this.alwaysInclude);
		}
		if (this.exposeContextBeansAsAttributes != null) {
			view.setExposeContextBeansAsAttributes(this.exposeContextBeansAsAttributes);
		}
		if (this.exposedContextBeanNames != null) {
			view.setExposedContextBeanNames(this.exposedContextBeanNames);
		}
		view.setPreventDispatchLoop(true);
		return view;
	}
 

 

 

 

 

 

 

 

0
0
分享到:
评论

相关推荐

    Spring MVC 解读——View,ViewResolver.zip

    在Spring MVC框架中,View和ViewResolver是两个关键的概念,它们负责将处理后的模型数据转换为用户可感知的视图,比如HTML页面。本文将深入解读这两个组件的工作原理及其重要性。 **一、View(视图)** 视图是...

    Spring5MVC源码.docx

    【Spring5MVC源码分析】 Spring MVC 是一个基于Java的、用于构建Web应用程序的、高度可插拔的MVC框架,它是Spring Framework的重要组成部分。Spring MVC的核心目标是简化前端控制器的开发,使得开发者可以专注于...

    spring mvc框架源码

    在本源码分析中,我们将探讨Spring MVC的工作原理、主要组件及其交互方式。 1. **DispatcherServlet**: 作为Spring MVC的前端控制器,DispatcherServlet是所有请求的入口点。它负责拦截请求,根据请求信息(如URL、...

    spring mvc mybatis 整合源码,带数据库脚本,带详细注释

    - Spring MVC是基于Model-View-Controller(MVC)设计模式的Web应用框架,提供了一种组织和处理请求的机制。 - 它的核心组件包括DispatcherServlet、HandlerMapping、HandlerAdapter、ModelAndView和ViewResolver...

    Spring.MVC-A.Tutorial-Spring.MVC学习指南 高清可复制版PDF

    首先,Spring MVC的核心设计理念是模型-视图-控制器(Model-View-Controller)架构模式。在该模式中,模型负责业务逻辑处理,视图负责展示数据,而控制器则作为模型和视图之间的桥梁,接收用户请求并调用相应的服务...

    Spring MVC 基础实例源码01

    在Spring MVC中,Model代表业务对象,View负责展示,Controller处理用户请求并协调Model和View。 2. **DispatcherServlet**:Spring MVC的入口点,它是一个前端控制器,接收所有HTTP请求,并根据配置的...

    Spring MVC jar包

    Spring MVC 是一个基于Java的轻量级Web应用框架,它为开发者提供了模型-视图-控制器(MVC)架构,使开发人员能够更好地组织和分离应用程序的业务逻辑、数据处理和用户界面。Spring MVC是Spring框架的一个核心组件,...

    Spring MVC学习指南

    ### Spring MVC 学习指南详解 #### 一、Spring MVC 概述 Spring MVC 是 Spring 框架的一部分,主要用于构建基于 Model-View-Controller (MVC) 设计模式的 Web 应用程序。它提供了丰富的功能来简化 Web 开发过程,...

    看透spring mvc源代码分析与实践扫描版带目录+源码

    通过深入学习Spring MVC的源码,开发者不仅可以更好地理解其内部机制,还能优化自己的代码,提升应用程序的性能和可维护性。这本扫描版书籍的源码分析部分,无疑会帮助读者在实践中应用这些知识,解决实际问题。

    springmvc项目源码

    通过深入学习这个 Spring MVC 项目源码,你可以掌握 MVC 设计模式的运用,了解 Spring 框架的组件协同工作方式,以及在实际项目中的最佳实践。这将有助于提升你的 Java Web 开发技能,更好地理解和使用 Spring MVC。

    Spring MVC 学习记录总结1

    Spring MVC 是一个广泛使用的 Java Web 开发框架,它实现了MVC(Model-View-Controller)设计模式,使得开发者可以更高效地构建可维护且松耦合的Web应用程序。在这个学习记录总结中,我们将深入理解Spring MVC的核心...

    最全最经典spring-mvc教程

    Spring MVC 是一款强大的Java Web开发框架,用于构建高效、可维护和模块化的Web应用程序。它作为Spring框架的一...通过学习这个教程,你可以提高你的Web开发技能,更好地利用Spring MVC来构建高质量的Java Web应用。

    spring MVC配置详解

    DispatcherServlet 是 Spring MVC 框架的核心组件,它负责转发每一个 Request 请求给相应的 Handler,Handler 处理以后再返回相应的视图(View)和模型(Model)。DispatcherServlet 是继承自 HttpServlet 的,既然 ...

    spring mvc源码实例

    这个源码实例应该是为了帮助开发者深入理解Spring MVC的工作原理和实现机制。下面,我们将详细探讨Spring MVC的关键知识点。 1. **DispatcherServlet**: 作为Spring MVC的核心组件,DispatcherServlet负责接收HTTP...

    Spring MVC 教程快速入门 深入分析

    二、Spring MVC核心类与接口:Spring MVC架构中包含许多核心组件,如DispatcherServlet、HandlerMapping、Controller、ViewResolver等。这些组件协同工作,处理用户的请求并返回相应的响应。 三、Spring MVC核心...

    spring MVC基础学习

    - 视图(View):负责渲染模型数据,Spring MVC支持多种视图技术如JSP、FreeMarker、Thymeleaf等。 5. **数据绑定与验证**: - 数据绑定:Spring MVC可以自动将请求参数绑定到Controller方法的参数上。 - 数据...

    Spring.MVC学习指南.pdf

    这份“Spring.MVC学习指南.pdf”很可能是为了帮助开发者深入理解和掌握Spring MVC的核心概念、工作原理以及实践技巧。下面将详细阐述Spring MVC的相关知识点。 1. **核心组件**: - **DispatcherServlet**:Spring...

    spring-mvc 基础功能之源码debug

    源码调试是学习Spring MVC的一个重要环节,它能帮助开发者理解框架内部的执行流程。通过设置断点,查看变量状态,跟踪方法调用,可以深入理解Spring MVC如何处理请求、如何进行依赖注入以及如何与视图交互。这种能力...

    Spring Mvc实例

    Spring MVC 是一个基于Java的轻量级Web应用框架,它是Spring框架的重要组成部分,主要用于构建Web应用程序的后端控制器。在本实例中,我们将探讨如何利用Spring MVC的注解来简化前后台交互,以及如何实现简单视图...

Global site tag (gtag.js) - Google Analytics