通过三个多月的核心技术和数据访问已经告一段落,接下来一段时间讲Spring MVC工做机制和原理。java
Spring Web MVC是基于Servlet API构建的原始Web框架,从一开始就包含在Spring框架中。正式名称“Spring Web MVC”来自其源模块(spring-webmvc
)的名称,但它一般称为“Spring MVC”。web
与Spring Web MVC并行,Spring Framework 5.0引入了一个反应式堆栈Web框架,其名称“Spring WebFlux”也基于其源模块(spring-webflux
)。算法
DispatcherServletspring
和许多其余web框架同样,Spring MVC是围绕前controller 模式设计的,其中一个重要的Servlet 为 DispatcherServlet,请求处理提供了一个共享算法,而实际工做则由可配置的委托组件执行。该模型灵活,支持多种工做流。typescript
DispatcherServlet做为Servlet,都须要使用Java配置或web.xml根据Servlet规范声明和映射。反过来DispatcherServlet使用Spring配置来发现请求映射、view解析、异常处理等所需的委托组件。微信
如下Java配置示例注册并初始化DispatcherServlet,它由Servlet容器自动检测:mvc
public class MyWebApplicationInitializer implements WebApplicationInitializer {
public void onStartup(ServletContext servletCxt) {
// 加载Spring web应用程序配置 AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext(); ac.register(AppConfig.class); ac.refresh();
// 建立并注册DispatcherServlet DispatcherServlet servlet = new DispatcherServlet(ac); ServletRegistration.Dynamic registration = servletCxt.addServlet("app", servlet); registration.setLoadOnStartup(1); registration.addMapping("/app/*"); }}
如下web.xml配置示例注册并初始化DispatcherServlet:app
<web-app>
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
<context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/app-context.xml</param-value> </context-param>
<servlet> <servlet-name>app</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value></param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
<servlet-mapping> <servlet-name>app</servlet-name> <url-pattern>/app/*</url-pattern> </servlet-mapping>
</web-app>
Spring Boot遵循不一样的初始化顺序。Spring Boot没有链接到Servlet容器的生命周期中,而是使用Spring配置来引导自身和嵌入式Servlet容器。在Spring配置中检测到过滤器和Servlet声明,并将其注册到Servlet容器中。框架
Context结构ide
DispatcherServlet须要WebApplicationContext(纯粹ApplicationContext的扩展)做为本身的配置。WebApplicationContext具备一个到ServletContext和Servlet的关联连接。它还绑定到ServletContext,这样应用程序能够在RequestContextUtils上使用静态方法,以便在须要访问WebApplicationContext时查找它。
对于许多应用程序来讲,拥有一个WebApplicationContext是简单和足够的。也能够有一个上下文层次结构,其中一个root WebApplicationContext在多个DispatcherServlet(或其余Servlet)实例中共享,每一个实例都有本身的子WebApplicationContext配置。
root WebApplicationContext一般包含基础设施bean,例如须要跨多个Servlet实例共享的数据存储库和业务服务。这些bean是有效继承的,能够在特定于Servlet的子WebApplicationContext中重写(即从新声明),该子WebApplicationContext一般包含给定Servlet的本地bean。下图显示了这种关系:
如下示例配置WebApplicationContext
层级结构:
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() { return new Class<?>[] { RootConfig.class }; }
protected Class<?>[] getServletConfigClasses() { return new Class<?>[] { App1Config.class }; }
protected String[] getServletMappings() { return new String[] { "/app1/*" }; }}
若是不须要应用程序上下文层次结构,则应用程序能够经过getRootConfigClasses()
返回全部配置,并经过getServletConfigClasses()
返回null
。
下面的示例显示了web.xml
的等效项:
<web-app>
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
<context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/root-context.xml</param-value> </context-param>
<servlet> <servlet-name>app1</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/app1-context.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
<servlet-mapping> <servlet-name>app1</servlet-name> <url-pattern>/app1/*</url-pattern> </servlet-mapping>
</web-app>
若是不须要应用程序上下文层次结构,则应用程序能够仅配置“root”上下文,并将contextConfigLocation
Servlet参数保留为空。
明天讲基于DispatchSevlet的 特殊Bean、Web MVC 配置、sevlet 配置等。
欢迎关注和转发Spring中文社区(加微信群,能够关注后加我微信):
本文分享自微信公众号 - Spring中文社区(gh_81d233bb13a4)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。