spring mvc是一个mvc开源框架,由于与spring是父子关系,所以无缝兼容
spring mvc入口:
<!-- spring MVC --> <servlet> <servlet-name>spring-mvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:/spring-mvc-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
spring mvc在web.xml中的配置如上,这是一个标准的servlet的配置,入口为:DispatcherServlet;
DispatcherServlet源码为:
public class DispatcherServlet extends FrameworkServlet { //省略实现代码... } public abstract class FrameworkServlet extends HttpServletBean { //省略实现代码...s } public abstract class HttpServletBean extends HttpServlet implements EnvironmentCapable, EnvironmentAware { //省略实现代码 }
由上面可知DispatcherServlet实现了HttpServlet接口,所以配置也使用servlet配置;
一个servlet的初始化时通过init()方法完成,那我们先从最顶层的类HttpServletBean看起,下面为HttpServletBean的init()方法的实现:
@Override public final void init() throws ServletException { if (logger.isDebugEnabled()) { logger.debug("Initializing servlet '" + getServletName() + "'"); } // Set bean properties from init parameters. try { PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties); BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this); ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext()); bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment())); initBeanWrapper(bw); bw.setPropertyValues(pvs, true); } catch (BeansException ex) { logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex); throw ex; } // Let subclasses do whatever initialization they like. //留给子类进行扩展 initServletBean(); if (logger.isDebugEnabled()) { logger.debug("Servlet '" + getServletName() + "' configured successfully"); } }
由上面的代码可知,方法前半部分做了一些初始化配置,initServletBean()被FrameworkServlet重写,下面是FrameworkServlet中initServletBean()的实现:
@Override protected final void initServletBean() throws ServletException { getServletContext().log("Initializing Spring FrameworkServlet '" + getServletName() + "'"); if (this.logger.isInfoEnabled()) { this.logger.info("FrameworkServlet '" + getServletName() + "': initialization started"); } long startTime = System.currentTimeMillis(); try { //创建上下文,创建容器 this.webApplicationContext = initWebApplicationContext(); initFrameworkServlet(); } catch (ServletException ex) { this.logger.error("Context initialization failed", ex); throw ex; } catch (RuntimeException ex) { this.logger.error("Context initialization failed", ex); throw ex; } if (this.logger.isInfoEnabled()) { long elapsedTime = System.currentTimeMillis() - startTime; this.logger.info("FrameworkServlet '" + getServletName() + "': initialization completed in " + elapsedTime + " ms"); } } //被调用方法实现,创建spring mvc容器的实现 protected WebApplicationContext initWebApplicationContext() { //获取父容器,即spring的容器 WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext()); WebApplicationContext wac = null; if (this.webApplicationContext != null) { // A context instance was injected at construction time -> use it wac = this.webApplicationContext; if (wac instanceof ConfigurableWebApplicationContext) { ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac; if (!cwac.isActive()) { // The context has not yet been refreshed -> provide services such as // setting the parent context, setting the application context id, etc if (cwac.getParent() == null) { // The context instance was injected without an explicit parent -> set // the root application context (if any; may be null) as the parent //设置父容器,父容器为spring的容器 cwac.setParent(rootContext); } configureAndRefreshWebApplicationContext(cwac); } } } if (wac == null) { // No context instance was injected at construction time -> see if one // has been registered in the servlet context. If one exists, it is assumed // that the parent context (if any) has already been set and that the // user has performed any initialization such as setting the context id wac = findWebApplicationContext(); } if (wac == null) { // No context instance is defined for this servlet -> create a local one wac = createWebApplicationContext(rootContext); } if (!this.refreshEventReceived) { // Either the context is not a ConfigurableApplicationContext with refresh // support or the context injected at construction time had already been // refreshed -> trigger initial onRefresh manually here. onRefresh(wac); } if (this.publishContext) { // Publish the context as a servlet context attribute. String attrName = getServletContextAttributeName(); getServletContext().setAttribute(attrName, wac); if (this.logger.isDebugEnabled()) { this.logger.debug("Published WebApplicationContext of servlet '" + getServletName() + "' as ServletContext attribute with name [" + attrName + "]"); } } return wac; }
有上面代码可知:spring mvc上下文和spring 上下文的关系,spring mvc容器为子容器, spring的容器为父容器,所以spring mvc里在配置controller时,可以直接引用在spring中配置的service类;所以在web.xml配置中,要先配置spring的配置,然后配置spring mvc的配置,否则spring mvc的子容器无法使用父容器中的资源
在FrameworkServlet类中onRefresh()方法是一个空方法,并没有具体实现,而是被子类重写了,在子类DispatcherServlet中onRefresh()方法实现如下:
@Override protected void onRefresh(ApplicationContext context) { initStrategies(context); } /** * Initialize the strategy objects that this servlet uses. * <p>May be overridden in subclasses in order to initialize further strategy objects. */ protected void initStrategies(ApplicationContext context) { initMultipartResolver(context); initLocaleResolver(context); initThemeResolver(context); initHandlerMappings(context); initHandlerAdapters(context); initHandlerExceptionResolvers(context); initRequestToViewNameTranslator(context); initViewResolvers(context); initFlashMapManager(context); }
由上面的代码可知在DispatcherServlet中刷新容器的时候,做了大量的初始化工作,初始化了Resolver,HandlerMapping,Adapter
初始化Resolver:
private void initLocaleResolver(ApplicationContext context) { try { //先从上下文里查找 this.localeResolver = context.getBean(LOCALE_RESOLVER_BEAN_NAME, LocaleResolver.class); if (logger.isDebugEnabled()) { logger.debug("Using LocaleResolver [" + this.localeResolver + "]"); } } catch (NoSuchBeanDefinitionException ex) { // We need to use the default. //上下文里没有则使用默认的 this.localeResolver = getDefaultStrategy(context, LocaleResolver.class); if (logger.isDebugEnabled()) { logger.debug("Unable to locate LocaleResolver with name '" + LOCALE_RESOLVER_BEAN_NAME + "': using default [" + this.localeResolver + "]"); } } }
关于默认的resolver:在DispatcherServlet刚开始有一段静态初始化的代码:
static { // Load default strategy implementations from properties file. // This is currently strictly internal and not meant to be customized // by application developers. 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()); } }
默认加载一个配置文件:与DispatcherServlet在同一个路径下DEFAULT_STRATEGIES_PATH;即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
配置文件中配置了默认的Resolver, HandlerMapping, HandlerAdapter, onRefresh()方法中要初始化的组件都有一个默认的配置。
上面的组件初始化基本都遵从了一个主要逻辑:先从容器或者资源里找,找不到就使用配置文件中默认配置的。
通过上面的代码spring mvc的初始化工作就完成了,上下文容器也就建立了!
相关推荐
【Spring5MVC源码分析】 Spring MVC 是一个基于Java的、用于构建Web应用程序的、高度可插拔的MVC框架,它是Spring Framework的重要组成部分。Spring MVC的核心目标是简化前端控制器的开发,使得开发者可以专注于...
在IT行业中,Spring MVC是一个广泛使用的Java Web框架,它提供了强大的模型-视图-控制器(MVC)架构来构建Web应用程序。这篇博客“spring-mvc 基础功能之源码debug”似乎深入探讨了Spring MVC的核心功能,并通过源码...
Spring MVC是Spring框架的一部分,专门用于构建Web应用程序。它采用模型-视图-控制器(Model-View-Controller,MVC)架构模式,将业务逻辑、数据处理和用户界面分离,使得应用更加模块化,易于维护。Spring MVC通过...
Spring MVC是Spring框架的一个核心模块,它用于构建Web应用程序的模型-视图-控制器(MVC)架构。这本书“看透Spring MVC源代码分析与实践”显然是为了帮助开发者深入理解Spring MVC的工作原理,并通过源码分析提升...
15. **兼容性与兼容性测试**:Spring MVC 4.0确保与各种Web容器的兼容性,如Tomcat、Jetty等,并提供了全面的兼容性测试。 以上就是Spring MVC 4.0的主要特点和知识点。这个版本在易用性、性能和功能方面都有显著...
【标题】"maven spring mvc示例源码"揭示了这...这个示例源码对于初学者理解Maven与Spring MVC的集成,以及如何构建一个完整的Java Web应用具有很高的参考价值。通过实际操作和调试,开发者可以更深入地掌握这些技术。
Spring MVC 是一个强大的Java Web开发框架,用于构建高效、可维护和模块化的Web应用程序。...通过分析这个大型项目源码,新手可以了解到Spring MVC的完整生命周期,以及如何组织和管理一个复杂Web应用程序的各个部分。
可用于分析spring mvc源码、spring mvc父子容器初始化流程、session和cookie机制、spring session等,也可以用于学习Java Web(servlet、filter、listener等)、spring源码等。 该项目使用servlet3.0规范,无web.xml...
Spring是个非常非常非常优秀的java框架,主要是用它的IOC容器帮我们依赖注入和管理一些...现在我们就来搭建一个利用Spring和Spring MVC结合的web工程最佳实践的例子。以Spring Framework 4.2.0为例,IDE为Myeclipse。
Spring MVC是Spring框架的一部分,用于构建Web应用程序。它处理HTTP请求,将请求映射到控制器,然后通过模型和视图进行响应。在OSGI中,Spring MVC可以被包装成一个bundle,与其他服务协同工作,提供Web接口供用户...
Spring MVC 提供了灵活的处理机制,包括处理器映射、视图解析、数据绑定、本地化和主题支持,以及对 RESTful 风格的 URL 支持,使得开发人员可以轻松地创建功能丰富的、高性能的 Web 应用。 ### 1. MVC 架构模式 ...
Spring MVC 是一个强大的Java Web开发框架,用于构建高效、可维护的Web应用程序。它基于Spring框架,提供了模型-视图-控制器(MVC)架构,简化了开发过程。本资源"Spring MVC step-by-step 源码"是针对初学者准备的...
1. Spring MVC:Spring MVC是Spring框架的一部分,专门用于构建Web应用程序的模型-视图-控制器(MVC)架构。它提供了处理HTTP请求、数据绑定、异常处理等功能,并通过DispatcherServlet作为入口点来协调各个组件。...
Spring MVC是Spring框架的一部分,专为Web应用设计。它遵循模型-视图-控制器(MVC)设计模式,将业务逻辑、用户界面和数据访问分离开来。Spring MVC通过DispatcherServlet作为入口点,处理HTTP请求,并根据请求映射...
这个项目源码提供了一个实战学习平台,帮助开发者理解和掌握Spring MVC与MyBatis的整合应用,同时可以了解到如何在实际项目中组织代码结构、配置文件以及进行测试。通过深入研究这些代码,你将能够更好地运用这两个...
《Pro.Spring.MVC.With.Web.Flow》是一本深入探讨Spring MVC框架和Web Flow技术的专业书籍,结合源码分析,为读者提供了全面理解这两种技术的详细路径。Spring MVC是Spring框架的一部分,用于构建高度可维护和可扩展...
1. **创建Spring配置**:首先,你需要创建一个Spring的配置文件,如`servlet-context.xml`,该文件定义了Spring MVC的组件,如DispatcherServlet、视图解析器和映射路径等。 2. **编写Controller**:接着,编写...
**Spring MVC**是Spring框架的一个模块,专门用于构建Web应用程序。它采用模型-视图-控制器(MVC)设计模式,分离了业务逻辑、数据和用户界面。请求由DispatcherServlet处理,然后转发给合适的控制器,控制器处理...
Spring MVC是Spring框架的一个模块,专为构建Web应用程序设计。它提供了一个模型-视图-控制器(MVC)架构,使得开发者可以更清晰地组织代码,提高代码的可维护性和测试性。Spring MVC通过DispatcherServlet作为前端...
Spring MVC是Spring框架的一个模块,专门用于构建Web应用程序。它提供了一个模型-视图-控制器(MVC)架构,使得开发者可以将业务逻辑、数据处理和用户界面分离,提高代码的可维护性和测试性。在Spring MVC中,...