10个知识点让你读懂Spring MVC容器

本文详细介绍了Spring框架中DispatcherServlet的配置方式,包括contextConfigLocation、ContextLoaderListener、WebApplicationContext和不同组件的装配过程。重点讨论了编程式配置、基于注解的控制器、HttpMessageConverter的使用以及如何处理XML和JSON。同时提到了使用@RestController和AsyncRestTemplate进行异步请求处理。
摘要由CSDN通过智能技术生成

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version=“3.0”>

contextConfigLocation

classpath:application-context.xml

org.springframework.web.context.ContextLoaderListener

web

org.springframework.web.servlet.DispatcherServlet

1

web

/

复制代码

  1. 在(1)处,通过contextConfigLocation参数指定业务层Spring容器的配置文件(多个配置文件用 , 分割)。

  2. 在(2)处,ContextLoaderListener是一个ServletLoaderListener,它通过contextConfigLocation指定的Spring配置文件启动业务层的Spring容器。

  3. 在(3)处,配置了名为web的DispatcherServlet,它默认加载/WEB-INF/web-servlet.xml(-servlet.xml)的Spring配置文件,启动Web层的Spring容器。Web层容器将作为业务层容器的子容器,Web层容器可以访问业务层容器的Bean,而业务层容器访问不了Web层容器的Bean。

  4. 在(4)处,通过指定DispatcherServlet处理 /* 全部的HTTP请求。一个web.xml可以配置多个DispatcherServlet,通过其对应的配置,让每个DispatcherServlet处理不同的请求。

DispatcherServlet 的配置参数

===========================

可以通过的属性指定配置参数:

  1. namespace参数:DispatcherServlet对应的命名空间,默认是WEB-INF/-servlet.xml。在显式配置该参数后,新的配置文件对应的路径是WEB-INF/.xml,例如如果将namespace设置为sample,则对应的Spring配置文件为WEB-INFmple.xml。

  2. contextConfigLocation:如果DispatcherServlet上下文对应的Spring配置文件有多个,则可以使用该属性按照Spring资源路径的方式指定,如classpath:sample1.xml,classpath:sample2.xml。

  3. publishContext:默认为true。DispatcherServlet根据该属性决定是否将WebApplicationContext发布到ServletContext的属性列表中,方便调用者可借由ServletContext找到WebApplicationContext实例,对应的属性名为DispatcherServlet#getServletContextAttributeName()的返回值。

  4. publishEvents:默认为true。当DispatcherServlet处理完一个请求后,是否需要向容器发布一个ServletRequestHandleEvent事件。

推荐观看:传送门

=======================================================

Spring容器配置

==============

<beans xmlns=“http://www.springframework.org/schema/beans”

xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”

xmlns:context=“http://www.springframework.org/schema/context”

xmlns:mvc=“http://www.springframework.org/schema/mvc”

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-4.0.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-4.0.xsd

http://www.springframework.org/schema/mvc

http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">

<context:component-scan base-package=“com.ankeetc.web”/>

<mvc:annotation-driven />

复制代码

基于编程的配置

===========

Spring 4.0已经全面支持Servlet 3.0,可以使用编程的方式配置Servlet容器。在Servlet 3.0环境中,容器会在类路径中查找实现javax.servlet.ServletContainerInitializer接口的类,如果发现实现类,就会用它来配置Servlet容器。Spring提供了这个接口的实现,名为SpringServletContainerInitializer,这个类反过来又查找实现WebApplicationInitializer的类并将配置的任务交给它们来完成。Spring还提供了一个WebApplicationInitializer基础实现类AbstractAnnotationConfigDispatcherServletInitializer,使得它在注册DispatcherServlet时只需要简单地指定它的Servlet映射即可。

public class WebApplicationInitilalizer implements WebApplicationInitializer {

@Override

public void onStartup(ServletContext servletContext) throws ServletException {

ServletRegistration.Dynamic registration = servletContext.addServlet(“web”, new DispatcherServlet());

registration.setLoadOnStartup(1);

registration.addMapping(“/”);

}

}

复制代码

DispatcherServlet的内部逻辑

==========================

protected void initStrategies(ApplicationContext context) {

initMultipartResolver(context);

initLocaleResolver(context);

initThemeResolver(context);

initHandlerMappings(context);

initHandlerAdapters(context);

initHandlerExceptionResolvers(context);

initRequestToViewNameTranslator(context);

initViewResolvers(context);

initFlashMapManager(context);

}

复制代码

DispatcherServlet#initStrategies()方法将在WebApplicationContext初始化后执行,此时Spring上下文中的Bean已经初始化完毕,该方法通过反射查找并装配Spring容器中用户自定义的Bean,如果找不到就装配默认的组件实例。

默认组件

========

在DispatcherServlet.properties配置文件里边,指定了DispatcherServlet所使用的默认组件。如果用户希望采用非默认的组件,只需在Spring配置文件中配置自定义的组件Bean即可。

本地化解析器

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

复制代码

10个知识点让你读懂Spring MVC容器

DispatcherServlet装配各型组件的逻辑

==============================

二、注解驱动的控制器

==============

@RequestMapping映射请求

=======================

  1. 在POJO类上标注@Controller,再通过 context:component-scan 扫描到该类,可以是POJO成为一个能处理HTTP请求的控制器。

  2. 在控制器的类定义和方法定义处都可以使用@RequestMapping映射对应的处理方法。

  3. @RequestMapping不但支持标准的URL,还支持Ant风格和{XXX}占位符的URL。

  4. @RequestMapping和value、method、params及headers分别表示请求路径、请求方法、请求参数及报文头的映射条件。

获取请求内容

==========

org.springframework.web.context.request

使用HttpMessageConverter

==========================

HttpMessageConverter接口可以将请求信息转换为一个对象(类型为T),并将对象(类型为T)绑定到请求方法的参数中或输出为响应信息。DispatcherServlet默认已经安装了RequestMethodHandlerAdapter作为HandlerAdapter组件的实现类,HttpMessageConverter即由RequestMethodHandlerAdapter使用,将请求信息转换为对象,或将对象转换为响应信息。

HttpMessageConverter的实现类

============================

Spring为HttpMessageConverter提供了众多的实现类:

10个知识点让你读懂Spring MVC容器

实现类

=======

10个知识点让你读懂Spring MVC容器

实现类

=======

10个知识点让你读懂Spring MVC容器

默认的HttpMessageConverter

===========================

RequestMappingHandlerAdapter已经默认装配了以下的HttpMessageConverter:

  • StringHttpMessageConverter

  • ByteArrayHttpMessageConverter

  • SourceHttpMessageConverter

  • AllEncompassingFormHttpMessageConverter

装配其他类型的HttpMessageConverter

===============================

如果需要装配其他类型的HttpMessageConverter,可以在Spring的Web容器上下文中自行定义一个RequestMappingHandlerAdapter,注册若干HttpMessageConverter。如果在Spring web容器中显式定义了一个RequestMappingHandlerAdapter,则Spring MVC将使用它 覆盖 默认的RequestMappingHandlerAdapter。

使用HttpMessageConverter

==========================

  1. 可以使用@RequestBody、@ResponseBody对处理方法进行标注

  2. 可以使用HttpEntity、ResponseEntity作为处理方法的入参或返回值

RestTemplate是Spring的模板类,可以使用该类调用Web服务端的服务,它支持Rest风格的URL。

结论

======

  1. 当控制器处理方法使用到@RequestBody、@ResponseBody 或 HttpEntity、ResponseEntity 时,Spring MVC才会使用注册的HttpMessageConvertor对请求、相应消息进行处理。

  2. 当控制器处理方法使用到@RequestBody、@ResponseBody 或 HttpEntity、ResponseEntity时,Spring 首先根据请求头或响应的Accept属性选择匹配的 HttpMessageConverter,进而根据参数类型或泛型类型的过滤得到匹配的 HttpMessageConverter,若找不到可用的 HttpMessageConverter 将报错。

  3. @RequestBody、@ResponseBody不需要成对出现。

处理XML和JSON

==============

Spring MVC提供了几个处理XML和JSON格式的请求、响应消息的HttpMessageConverter:

  • MarshallingHttpMessageConverter:处理XML

  • Jaxb2RootElementHttpMessageConverter:处理XML,底层使用JAXB

  • MappingJackson2HttpMessageConverter:处理JSON格式

只要在Spring Web容器中为RequestMappingHandlerAdapter装配好相应的HttpMessageConverter,并在交互中通过请求的Accept指定MIME类型,Spring MVC就可以是服务器端的处理方法和客户端透明的通过XML或JSON格式进行通信。

复制代码

使用@RestController

=====================

@RestController已经标注了@ResponseBody和@Controller,可以直接在控制器上标注该注解,就不用在每个@RequestMapping方法上添加@ResponseBody了。

AsyncRestTemplate

=====================

Spring 4.0提供了AsyncRestTemplate用于以异步无阻塞的方式进行服务访问。

public class WebApplicationInitilalizer implements WebApplicationInitializer {

@Override

public void onStartup(ServletContext servletContext) throws ServletException {

ServletRegistration.Dynamic registration = servletContext.addServlet(“web”, new DispatcherServlet());

registration.setLoadOnStartup(1);

// 此处要设置为true

registration.setAsyncSupported(true);

registration.addMapping(“/”);

}

}

@RestController

public class AsyncController {

@RequestMapping(value = “/async”, method = RequestMethod.GET)

public Callable async() {

System.out.println(“hello!”);

return new Callable() {

@Override

public String call() throws Exception {

TimeUnit.SECONDS.sleep(5);

return “ASYNC”;

}

};

}

}

public class Main {

public static void main(String[] args) {

AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate();

ListenableFuture<ResponseEntity> future = asyncRestTemplate.getForEntity(“http://localhost:8080/async”, String.class);

System.out.println(“return”);

future.addCallback(new ListenableFutureCallback<ResponseEntity>() {
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

结尾

查漏补缺:Java岗 千+道面试题Java基础+全家桶+容器+反射+异常等

这不止是一份面试清单,更是一种”被期望的责任“,因为有无数个待面试者,希望从这篇文章中,找出通往期望公司的”钥匙“,所以上面每道选题都是结合我自身的经验于千万个面试题中经过艰辛的两周,一个题一个题筛选出来再次对好答案和格式做出来的,面试的答案也是再三斟酌,深怕误人子弟是小,影响他人仕途才是大过,也希望您能把这篇文章分享给更多的朋友,让他帮助更多的人,帮助他人,快乐自己,最后,感谢您的阅读。

由于细节内容实在太多啦,在这里我花了两周的时间把这些答案整理成一份文档了,在这里只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!
更新!**

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

结尾

[外链图片转存中…(img-AggOlax9-1711947354062)]

这不止是一份面试清单,更是一种”被期望的责任“,因为有无数个待面试者,希望从这篇文章中,找出通往期望公司的”钥匙“,所以上面每道选题都是结合我自身的经验于千万个面试题中经过艰辛的两周,一个题一个题筛选出来再次对好答案和格式做出来的,面试的答案也是再三斟酌,深怕误人子弟是小,影响他人仕途才是大过,也希望您能把这篇文章分享给更多的朋友,让他帮助更多的人,帮助他人,快乐自己,最后,感谢您的阅读。

由于细节内容实在太多啦,在这里我花了两周的时间把这些答案整理成一份文档了,在这里只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!

  • 18
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值