SpringMVC总结(xml配置和java类配置)

文章目录

    • 1.简单介绍
    • 2.需要解决的问题
    • 3.SpringMVC工作流程
    • 4.Spring的版本变迁
      • 1. 2004.03 发布spring1.0
      • 2. 2006.10 发布spring2.0
      • 3. 2007.11 发布spring2.5
      • 4. 2009.12 发布Spring3.0
        • 4.1 引入Restful架构风格支持
        • 4.2 引入mvc XML命名空间
        • 4.3 新增注解支持
        • 4.6 文件上传支持
      • 5. Spring3.1对Servlet3.0全面支持
        • 5.1 新增@EnableWebMvc注解
        • 5.2 新增@ConponentScan注解
        • 5.3 新的@Controller和@RequestMapping注解类
        • 5.4 新的@ExceptionHandler注解支持类
        • 5.5 @RequestMapping的consumes和prodoces条件支持
        • 6. 提供FlashMapManager
      • 6. 2013.12 发布了Spring4.0
      • 7. 2017.9 发布了Spring5
    • 5. 搭建环境-基于xml配置
      • 5.1 导入必要的jar包
      • 5.2 web.xml配置DispatcherServlet
      • 5.3 web.xml组件介绍
      • 5.4 spring-mvc.xml
        • 5.4.1 Spring-mvc.xml需要实现的基本功能:
        • 5.4.2 context:component-scan介绍
        • 5.4.3 mvc:annotation-driven介绍
        • 5.4.4 conversion-service
        • 5.4.5 interceptor 拦截器
          • 5.4.5.1.定义interceptor实现类
          • 5.4.5.2 将定义的拦截器类加到SpringMVC的拦截体系中
    • 6.环境搭建-基于注解配置
    • 7. 环境搭建-基于java类的配置

1.简单介绍

Spring MVC是Spring框架中用于Web应用快速开发的一个模块,基于Servlet API构建的原始WEB框架,正式名称是"Spring Web MVC",来自于它的源模块(spring-webmvc),不过我们通常称之为Spring MVC。其中MVC是Model-View-Controller的缩写。主要是DispatcherServlet。

2.需要解决的问题

  • 1.Spring MVC的工作流程?
  • 2.Spring MVC中DispatcherServlet的配置方式

3.SpringMVC工作流程

  1. 客户端向服务端发送请求,请求首先发送到DispatcherServlet(前端控制器)

  2. DispatcherServlet接收到请求后,会使用HandlerMapping类(映射处理器)遍历查找具体的Handler(也就是Controller)。根据request请求的URL等信息查找能够处理的Handler。

  3. handlerMapping找到对应的Handler,并不是直接返回一个Handler原始对象,而是一个Handler执行链。这个执行链中包含了拦截器和处理请求的Handler。

  4. 即如果配置了拦截器intercrptor,会构造HandlerExecutionChain类,HandlerMapping类会将这个类的对象返回给DispatcherServlet

  5. DispatcherServlet拿到返回的Handler后会调用HandlerAdapter类去执行Handler

  6. HandlerAdapter类执行完成Handler后返回一个ModelAndView对象(封装了处理结果数据和视图名称信息)给DispatcherServlet

  7. DispatcherServlet接收到ModelAndView后,会根据视图名来调用viewResolver类进行视图解析

  8. viewResolver类根据逻辑视图解析成一个真正的view视图返回给DispatcherServlet

  9. DispatcherServlet接收到view视图后,根据model进行视图中数据的填充,即视图渲染,完成后返回给客户端。

4.Spring的版本变迁

1. 2004.03 发布spring1.0

源码只有一个jar包。包含了aop,beans,context,core,jdbc,orm等。仅支持xml配置。

2. 2006.10 发布spring2.0

1.增加了对于注解的配置。提供了XML命名空间和AspectJ支持。

@Repository 将数据访问层的类标识为Bean。

2.applicationContext.xml文件的头文件由1.2的.dtd规则变成了.xsd规则。

Spring2.5之前,通过实现Controller接口来定义处理器类。

3. 2007.11 发布spring2.5

1.提供了若干新特性用于简化web应用开发部署,支持jdk5。

2.添加了可扩展的xml配置,新增了注解驱动配置,引入了完整的Annotation,无需使用Controller继承接口的方式,而是基于@Controller和@RequestMapping等注解配置MVC应用 。

需要通过处理器映射DefaultAnnotationHandlerMapping和处理器适配器AnnotationMethodHandlerAdapter开启支持@Controller和@RequestMapping注解的处理器。

  • @Component: 泛化,表示一个Bean,可作用于任何层次;
  • @Controller:用于标识是处理器类;
  • @Service:标注service实现类
  • @RequestMapping:请求到处理器功能方法的映射规则;
  • @RequestParam:请求参数到处理器功能处理方法的方法参数上的绑定;
  • @ModelAttribute:请求参数到命令对象的绑定;
  • @SessionAttributes:用于声明session级别存储的属性,放置在处理器类上,通常列出模型属性(如@ModelAttribute)对应的名称,则这些属性会透明的保存到session中。
  • @InitBinder:自定义数据绑定注册支持,用于将请求参数转换到命令对象属性的对应类型。

3.增加了注释驱动annotation-driven的配置支持。

4.提供了对JSR-250的支持

JSR-250规范定义了两个用于指定声明周期方法的注解:

@PostConstruct:初始化之后执行的回调方法 ,替代init-method

@PreDestory:销毁之前的回调方法,替代destory-method

使用时还需要激活Bean的后处理器。在xml文件中添加:context:annotation-config

5.Spring web mvc不再在spring.jar中,发布在lib/modules下。包是spring-webmvc.jar和spring-webmvc-protler.jra。

4. 2009.12 发布Spring3.0

随着java EE规范一起发布,支持jdk6。分成了多个jar包进行管理。

4.1 引入Restful架构风格支持

通过@PathVariable注解和一些其他特性支持。

  • @CookieValue:cookie数据到处理器功能处理方法的方法参数上的绑定;
  • @RequestHeader:请求头(header)数据到处理器功能处理方法的方法参数上的绑定;
  • @RequestBody:请求的body体的绑定(通过HttpMessageConverter进行类型转换);
  • @ResponseBody:处理方法的返回值作为响应体(通过HttpMessageConverter进行类型转换);
  • @ResponseStatus:定义处理器功能处理方法/异常处理器返回的状态码和原因;
  • @ExceptionHandler:注解式声明异常处理器;
  • @PathVariable:请求URI中的模板变量部分到处理器功能处理方法的方法参数上的绑定,从而支持RESTful架构风格的URI

4.2 引入mvc XML命名空间

用于支持mvc配置。

  • mvc:annotation-driven:自动注册基于注解风格需要的DefaultAnnotationHandlerMapping,AnnotationMethodHandlerAdapter

  • mvc:interceptors:注册自定义的处理器拦截器;

  • mvc:view-controller:和ParameterizableViewController类似,收到相应请求后直接选择相应的视图;

  • mvc:resources:逻辑静态资源路径到物理静态资源路径的支持;

  • mvc:default-servlet-handler:当在web.xml中DispatcherServlet使用/映射时,能映射静态资源(当Spring Web MVC框架没有处理请求对应的控制器时(如一些静态资源),转交给默认的Servlet来响应静态文件,否则报404找不到资源错误)等等。

4.3 新增注解支持

1.添加了@Configuration,将该注解标注在类上,将该类作为spring.xml文件中的 ,保证bean的作用域。配置spring容器,等价于applicationContext.xml。

2.新增了mvc XML的命名空间用于支持mvc配置,简化了Spring MVC的配置。添加了@CookieValue,@RequestHeaders等注解对mvc进行增强。web部分主要分为:web,Servlet,Portlet,Strtus四个模块。

3.web.xml的顶层标签有一个metadata-complete属性,用来指定当前的部署描述文件是否是完全的,为true表示容器只依赖web.xml,将会忽略所有的注解(同时会跳过web-fragment.xml的扫描),也叫禁用可插性支持。为false则表示启动注解支持。默认为false。

Servlet3.0新增了若干个注解,@WebServlet,@WebFilter,@webListener用于简化servlet,filter,listener的声明。使得web.xml部署符不再是必须的。使用注解配置可以更加直观的看到Servlet跳转页面或者其他的功能。

4.6 文件上传支持

在此之前,servlet本身没有对此提供直接的支持,需要使用第三方框架。Servlet3.0中提供了该功能。

HttpServletRequest提供了两个方法用于从请求中解析出上传的文件

Part getPart(String name) 获取请求中给定name的文件

CollectiongetParts() 获取所有的文件

每一个文件用一个javax.servlet.http.Part对象来表示。可以与@MultipartConfig注解配合使用,进行一些自定义的配置。

5. Spring3.1对Servlet3.0全面支持

5.1 新增@EnableWebMvc注解

用于在基于java类定义Bean配置中开启MVC支持。

5.2 新增@ConponentScan注解

用来代替spring-mvc.xml中的component-scan元素,开启组件扫描,自动扫描包路径下@ComponentScan注 解进行注册Bean实例。

5.3 新的@Controller和@RequestMapping注解类

处理器映射RequestMappingHandlerMapping和处理器适配器RequestMappingHandlerAdapter。

5.4 新的@ExceptionHandler注解支持类

ExceptionHandlerExceptionResolver来代替3.0的AnnotationMethodHandlerExceptionResolver

5.5 @RequestMapping的consumes和prodoces条件支持

用于支持@RequestBody和@ResponseBody.

consumes指定请求的内容是什么类型的内容,即处理方法消费什么类型的数据,

如:consumes="application/json"表示json类型的内容。spring会根据相应的HttpMessageConverter进行请求内容区数据到@RquestBody注解的命令对象的转换。

produces 指定生产什么类型的内容

如produces="application/json"表示JSON类型的内容,Spring的根据相应的HttpMessageConverter进行请求内容区数据到@RequestBody 注解的命令对象的转换,Spring 会根据相应的HttpMessageConverter进行模型数据(返回值)到JSON响应内容的转换。

6. 提供FlashMapManager

Spring Web MVC提供了flashMapManager用于管理FlashMap,默认使用SessIonFlashMapManager。即数据默认存储在session中。

6. 2013.12 发布了Spring4.0

Spring4.X新特性参照:Spring4.x的新特性

  • 进行了重大升级,开始全面支持jdk8,jdk8的时间和日期API,重复注解,optiona,Lambda表达式。
  • 增强了Spring MVC,主要基于servlet3.0开发。去除了struts模块(spring-strtus)
  • 增加了WebSocket模块(spring-websocket)。
  • 提供了RestController注解,替代了@Controller+@ResponseBody组合返回json。
  • 以及提供AsyncRestTemplate支持客户端的异步无阻塞请求。
  • web部分变成了:webSocket,Servlet,Web,Portlet。

7. 2017.9 发布了Spring5

升级到了jdk8,将java8,javaee7作为最低版本要求,增加了新的spring-webflux模块,基于reactive的spring-webmvc,完全的异步非阻塞。旨在使用enent-loop 执行模型和传统的线程池模型。web部分变成了:WebSocket,WebMVC,web,WebFlux。

5. 搭建环境-基于xml配置

5.1 导入必要的jar包

首先需要引入spring-webmvc-x.y.z.jar 。里面包含了DispatcherServlet类。

springmvc依赖Apache Commons Logging组件。commons-logging-x.y.z.jar

tomcat7默认使用servlet3.0,tomcat8和8.5X默认使用Servlet3.1。tomcat9使用4.0

<dependency>
    <groupId>javax.servletgroupId>
    <artifactId>javax.servlet-apiartifactId>
    <version>3.1.0version>
    <scope>providedscope>
dependency>
<dependency>
    <groupId>org.springframeworkgroupId>
    <artifactId>spring-webmvcartifactId>
    <version> 4.1.5.RELEASEversion>
dependency>

5.2 web.xml配置DispatcherServlet

servlet3.0之前的部署工作必须要一个部署描述符,即web.xml。

servlet3.0+的版本进行了规范,允许servlet,filter,listener不必在web.xml中声明,以硬编码的方式存在,实现容器的零配置。


<web-app id="WebApp_ID" version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 
    
    
	<context-param>
		<param-name>contextConfigLocationparam-name>
        
		<param-value>
			classpath*:applicationContext*.xml
		param-value>
	context-param>
    
    
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        listener-class>
    listener>
    
<servlet>
    
    <servlet-name>dispatcherServletservlet-name>
    
    <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
	
    <init-param>
        <param-name>contextConfigLocationparam-name>
        
        <param-value>classpath:spring-*.xmlparam-value>
    init-param>
    
	<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
	<servlet-name>dispatcherServletservlet-name>
    
	<url-pattern>/url-pattern>
servlet-mapping>
    
     
	<filter>
        
		<filter-name>encodingFilterfilter-name>
		<filter-class>
			org.springframework.web.filter.CharacterEncodingFilter
		filter-class>
		<init-param>
			<param-name>forceEncodingparam-name>
			<param-value>trueparam-value>
		init-param>
		<init-param>
			<param-name>encodingparam-name>
			<param-value>UTF-8param-value>
		init-param>
	filter>
    
	<filter-mapping>
		<filter-name>encodingFilterfilter-name>
		<url-pattern>/*url-pattern>
	filter-mapping>  
    
    
    <session-config>
        <session-timeout>60session-timeout>
    session-config>
    
    
    <error-page>
        
		<exception-type>java.lang.Exceptionexception-type>
		<location>/frame/errorpage/exception.jsplocation>
	error-page>
	<error-page>
        
		<error-code>404error-code>
		<location>error.htmllocation>
	error-page>
    
    
    <welcome-file-list>
        
		<welcome-file>mainfordiscern.jspwelcome-file>
	welcome-file-list>
    
web-app>

配置了一个名称为dispatcherServlet的Servlet,类型是DispatcherServlet,是Srping MVC的入口。自动启动,会mapping所有的请求。通过设置contextConfigLocation参数指定SpringMVC配置文件的位置,通过url-pattern元素配置成,将所有请求的url映射到该servlet。

5.3 web.xml组件介绍

web.xml中相关组件启动顺序为:context-name -> listener -> filter -> servlet

1.解析context-param 中的键值对

2.创建一个application内置对象,即servletContext,servlet上下文 用于全局共享

3.将context-param的键值对放入servletContext中,web应用内全局共享

4.读取listener标签创建监听器,在servlet2.3-servlet3版本中可以采取ContextLoaderListener和ContextLoaderServlet,但是在Spring3中移除了ContextLoaderServlet。这里使用ContextLoaderListener实现类,Spring会创建一个WebapplicationContext类(IOC容器)的对象,这个IOC容器是 根IOC容器(全局性),将它放入到servletContext中,作为应用中全局共享。键名为:WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE.可以通过两种方式获取。

WebApplicationContext applicationContext = (WebApplicationContext)application
				.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);

WebApplicationContext applicationContext1WebApplicationContextUtils
				.getWebApplicationContext(application);

全局的根IOC容器只能获取到该容器中创建的Bean,不能访问到其他容器创建的Bean,即不能读取web.xml配置的contextConfigLocation参数的applicationContext*.xml文件来创建的Bean。

5.listener创建完成之后创建filter

6.初始化创建servlet,即这里的DispatcherServlet

7.DispatcherServlet的父类FrameworkServlet会重写其父类的initServletBean方法,并调用initWebApplicationContext()以及onRefresh();

8.initWebApplicationContext()方法会创建一个当前servlet的一个IOC子容器,如果存在WebApplicationContext则将它设置为父容器,不存在父容器则设置为null。

9.读取servlet标签的init-param配置的spring-xml文件并加载相关的Bean

10onRefresh()方法创建web应用相关组件。

5.4 spring-mvc.xml



<beans default-lazy-init="true"
    xmlns="http://www.springframework.org/schema/beans" 
    xmlns:p="http://www.springframework.org/schema/p"
    
	xsi:schemaLocation="  
		
       http://www.springframework.org/schema/beans   
       http://www.springframework.org/schema/beans/spring-beans-4.3.xsd 
		
       http://www.springframework.org/schema/mvc   
       http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd  
 		
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
		
       http://www.springframework.org/schema/tx   
       http://www.springframework.org/schema/tx/spring-tx-4.3.xsd   
       http://www.springframework.org/schema/context  
       http://www.springframework.org/schema/context/spring-context-4.3.xsd" >  

<context:component-scan base-package="com.ppxx,com.command" use-default-filters="false">
    
context:component-scan>
	
    <mvc:annotation-driven conversion-service="conversionService" />
    <bean id="conversionService"     class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    bean>
       
    
    
	<mvc:interceptors>
		<mvc:interceptor>
			<mvc:mapping path="/**"/>
            
			<mvc:exclude-mapping path="/toLogin.do"/>
            <mvc:exclude-mapping path="/toRegist.do"/>
			<mvc:exclude-mapping path="/checkcode.do"/>
			<bean class="com.ppxx.interceptors.SessionInterceptor"/>	
		mvc:interceptor>
	mvc:interceptors>
    
    <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        
        <property name="prefix" value="/WEB-INF/pages/" />
        <property name="suffix" value=".jsp" />
        <property name="order" value="0" />
        <property name="contentType" value="text/html;charset=UTF-8" />
    bean>     
    
    <bean id="multipartResolver"
          class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        
        <property name="defaultEncoding" value="utf-8" />
        
        <property name="maxUploadSize" value="10485760000" />
        
        <property name="maxInMemorySize" value="40960" />
    bean>

beans>

5.4.1 Spring-mvc.xml需要实现的基本功能:

1.首先需要在spring-mvc.xml文件中声明spring-context

2.接着应用context:component-scan 元素。

3.配置mvc:annotation-driven/

4.配置视图解析器

5.4.2 context:component-scan介绍

配置此标签来扫描通过注解配置的类。

context:component-scan中的属性:
use-default-filters:Indicates whether automatic detection of classes annotated with @Component, @Repository, @Service, or @Controller should be enabled. Default is “true”
默认true,会扫描指定包下所有类上的注解,将类注册成bean。

@Component 基本注解,标识一个受Spring管理的Bean组件

@Repository 指定此类是一个容器类,是DAO层类的实现。标识持久层Bean组件

@Service 指定为Service类,标识持久层Bean组件,默认情况会自动加载它到spring容器中。

@Controller 标识表现层Bean组件

@Autowried 自动注入

@Scope 指定此spring bean的scope是单例

context:component-scan还提供了两个子标签:

context:include-filter 指定扫描

context:exclude-filter 指定不扫描

如果认为扫描的粒度较大,只想扫描到指定包的Controller层,便可以通过

设置成只扫描controller层。同时需要将use-default-filter设置成false。

当然如果所有的Controller类都在同个子包下,可以将base-package=“com.ppxx.controller”

注意:context:component-scan只允许有两个子节点。

filter中type的表达式有多种:

Type Examples Expression Description
annotation org.example.SomeAnnotation 符合SomeAnnoation的target class
assignable org.example.SomeClass 指定class或interface的全名
aspectj org.example…*Service+ AspetJ语法
regex org.example.Default.* Regelar Expression
custom org.example.MyTypeFilter org.springframework.core.type.TypeFilter(Spring3新增)

5.4.3 mvc:annotation-driven介绍

mvc:annotation-driven是SpringMVC 提供的一键式配置方法,Spring3.2+版本实现。配置此标签会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter 两个bean,是spring MVC为@Controllers分发请求所必须的。

5.4.4 conversion-service

为了在Spring MVC应用程序中使用Formatter,需要用到ConversionService的bean对它进行注册,

1.Spring通过ConversionService进行类型转换,通过ConverterRegistry中的add方法注册一个转换器

2.ConversionService中的canConverter判断是否可以转换,convert调用相应的转换器进行类型转换操作。

5.4.5 interceptor 拦截器

interceptor拦截器作用于拦截用户的请求并作相应的处理。可以进行权限验证,或者判断用户是否登录等等。

那么如何实现呢?

5.4.5.1.定义interceptor实现类

实现有两种方式

1.SpringmVC中的interceptor拦截请求是通过HandlerInterceptor来实现的。所以要定义的interceptor类需要去实现这个接口,或者继承实现了HandlerInterceptor接口的类。比如说抽象类HandlerIntercreptorAdapter。

两者的区别在于,如果直接去实现HandlerInterceptor,需要显式的重写接口的三个方法,而继承不需要。

2.当然也可以通过实现Spring的WebRequestInterceptor接口或者继承实现了WebRequestInterceptor接口的类。

这里是通过实现HandlerInterceptor接口来实现Seesion验证的拦截器:

/**
 * 用于session验证的拦截器
 */
public class SessionInterceptor implements HandlerInterceptor {
	
    /**在整个请求结束之后,即DispatcherServlet渲染了对应视图之后执行。
     * 主要作用于进行资源清理工作。
     */
	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {

	}
	/**在当前请求进行处理之后,即Controller方法调用之前,DispatcherServlet进行视图返回渲染之前执行
	 * 多个postHandler调用顺序与preHandle相反。即先声明的Interceptor中的postHandler反而会后执行
	 * 可以对Controller处理之后的ModelAndView对象进行操作。
	 */
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
			throws Exception {

	}
	/**在请求处理之前进行调用,SpingMVC中可以设置多个Intercreptor,
	 *最先执行的都是Interceptor中的preHandler方法,根据声明顺序依次执行
	 *在方法中进行一些前置初始化操作或者对当前请求进行预处理。或者进行一些判断决定请求是否继续
	 *@retrun	false表示请求结束 ,后续的Intercreptor和Controller不再执行。
	 *			true 继续调用下一个Intercreptor的preHandler方法,然后调用Controller
	 */
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
		System.out.println("preHandle()");
		HttpSession session = request.getSession();
		Object obj = session.getAttribute("userName");
		if (null == obj) {
			// 没有登录,重定向到登录页面
			response.sendRedirect("toLogin.do");
			return false;
		}
		// 登录过,则继续向后调用
		return true;
	}
}
5.4.5.2 将定义的拦截器类加到SpringMVC的拦截体系中

1.首先需要在spring-mvc.xml中添加支持mvc的schema,这样就可以使用mvc标签了。

2.使用mvc:interceptor标签声明需要加入到SpringMVC拦截器链路中的拦截器类。

6.环境搭建-基于注解配置

在servlet3.0之前的版本中,servlet,filter,listener等都需要在web.xml文件中进行配置(servlet3.0也支持),但是servlet3.0中引入了注解,只需要在对应的Servlet类上使用@WebServlet注解进行标记。应用程序启动之后就会访问到该servlet。载配合其他注解实现无xml配置servlet。

@WebServlet(urlPatterns = "/demo", asyncSupported = true)
public class AsyncDemoServlet extends HttpServlet {

	@Override
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
    throws IOException, ServletException {
        resp.setContentType("text/html;charset=UTF-8");
        PrintWriter out = resp.getWriter();
        out.println("进入Servlet的时间:" + new Date() + ".");
        out.flush();
        //在子线程中执行业务调用,并由其负责输出响应,主线程退出
        AsyncContext ctx = req.startAsync();
        //监听器,提供了四种方法监听四种事件
        ctx.addListener(new AsyncListener() {
            //异步线程执行超时时
			public void onTimeout(AsyncEvent arg0) throws IOException {
			}
            //异步线程开始时
			public void onStartAsync(AsyncEvent arg0) throws IOException {
			}
            //异步线程出错时
			public void onError(AsyncEvent arg0) throws IOException {
			}
            //异步线程执行完毕时
			public void onComplete(AsyncEvent arg0) throws IOException {
			}
		});
        new Thread(new Executor(ctx)).start();
        out.println("结束Servlet的时间:" + new Date() + ".");
        out.flush();
    }
      @Override  
   	protected void doPost(HttpServletRequest request,  
         HttpServletResponse response) throws ServletException, IOException {  
      response.getWriter().write("Hello User.");  
   }  
}
 class Executor implements Runnable {
    private AsyncContext ctx = null;
    public Executor(AsyncContext ctx){
        this.ctx = ctx;
    }
    public void run(){
        try {
            //等待十秒钟,以模拟业务方法的执行
            Thread.sleep(10000);
            PrintWriter out = ctx.getResponse().getWriter();
            out.println("业务处理完毕的时间:" + new Date() + ".");
            out.flush();
            ctx.complete();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

@WebServlet有两个属性用来表示Servlet的访问路径。value和urlPatterns。注意不能同时使用。

通过@WebServlet注解,便可以将该类声明为Servlet,在部署的时候就会被容器处理。但是在springmvc中,想要去声明DispatcherServlet,无法在源码上加上这个注解。所以这种方式无法在springmvc中使用。

7. 环境搭建-基于java类的配置

1.Servlet3.0定义了一个接口ServletContainerInitializer,通过实现该接口,完成servlet,filter,listener的注册。

后来又进行了简化,只需要继承AbstractAnnotationConfigDispatcherServletInitializer类即可。通过该类中的getRootConfigClasses和getServletConfigClasses方法返回配置类。

2.通过@Configuration和@Component注解替代applicationContext.xml。使用@Configuration注解需要作为配置的类,替代xml中的定义bean的元数据;使用@Bean注解相应的方法,该方法名默认就是Bean的名称,该方法的返回值就是Bean的对象;使用@ComponentScan的参数中指定要扫描的包名和要过滤的类。@ComponentScan要过滤的类通常有两种:一种是留给mvc容器的,一种是mvc容器本身的配置类。

3.通过@EnableMvc注解或者继承WebMvcConfigurationSupport或者WebMvcConfigurerAdapter来配置mvc容器。

Servlet3.0+环境中 通过java配置DispatcherServlet。Servlet容器自动检测该类。

public class MyWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletCxt) {

        // Load Spring web application configuration
        AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();
        ac.register(AppConfig.class);
        ac.refresh();

        // Create and register the DispatcherServlet
        DispatcherServlet servlet = new DispatcherServlet(ac);
        ServletRegistration.Dynamic registration = servletCxt.addServlet("app", servlet);
        registration.setLoadOnStartup(1);
        registration.addMapping("/app/*");
    }
}

WebApplicationInitializer是Spring MVC提供的接口,确保基于java类代码的配置被检测到并自动初始化servlet。

AbstractAnnotationConfigDispatcherServletInitializer继承了AbstractDispatcherServletInitializer抽象类,这个抽象类继承了AbstractContextLoaderInitializer抽象类,这个抽象类就实现了WebApplicationInitializer接口。通过这个类可以更加容易地注册DispatcherServlet。

基于java的spring配置,建议使用该方法:

public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        //如果不需要应用程序上下文层次结构,可以返回null。
        return new Class<?>[] { RootConfig.class };
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        //AppConfig类是自定义,用来配置mvc处理。
        return new Class<?>[] { AppConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }
}

AppConfig配置:

@Configuration
//@EnableWebMvc 使用该注解来开启mvc支持 
@ComponentScan("org.keyou.web") 
public class AppConfig extends WebMvcConfigurerAdapter {
    @Bean
    public InternalResourceViewResolver  viewResolver(){
        InternalResourceViewResolver viewResolver=new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/views/");
        viewResolver.setSuffix(".jsp");
        viewResolver.setOrder(1);
        return viewResolver;
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/js/**").addResourceLocations("/WEB-INF/js/");
        registry.addResourceHandler("/css/**").addResourceLocations("/WEB-INF/css/");
        registry.addResourceHandler("/images/**").addResourceLocations("/WEB-INF/images/");
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
}

基于xml的spring配置,建议使用该方法

public class MyWebAppInitializer extends AbstractDispatcherServletInitializer {

    @Override
    protected WebApplicationContext createRootApplicationContext() {
        return null;
    }

    @Override
    protected WebApplicationContext createServletApplicationContext() {
        XmlWebApplicationContext cxt = new XmlWebApplicationContext();
        cxt.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");
        return cxt;
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }
}

dispatcher-config.xml:


<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="org.keyou.web"/>
    
beans>

参考资料:

Spring MVC 学习指南(第2版) [美]Paul Deck 著 林仪明 译
Spring官网

你可能感兴趣的:(Sping)