SpringMVC--运行流程、与Spring整合

运行流程

  1. 所有请求,前端控制器(DispatcherServlet)收到请求,调用doDispatch进行处理
  2. 根据HandlerMapping中保存的请求映射信息找到,处理当前请求的处理器执行链(包含拦截器)
  3. 根据当前处理器找到它的HandlerAdapter(适配器)
  4. 拦截器的preHandle先执行
  5. 适配器执行目标方法,并返回ModelAndView
    1). ModelAttribute注解标注的方法提前运行
    2). 执行目标方法的时候(确定目标方法用的参数):
    a. 有注解(如@RequestParam),从请求中获取参数值
    b. 没注解:
    - 看是否是原生API(如HttpServletRequest),直接传入原生API
    - 看是否为Model、Map以及其他的BindingAwareModelMap
    - 如果是自定义类型:
    * 看隐含模型中有没有,如果有就从隐含模型中拿
    * 如果没有,再看是否有SessionAttributes标注的属性,如果是从Session中拿,如果拿不到或抛出异常
    * 如果都没有,则通过反射创建对象
  6. 拦截器的postHandle执行
  7. 处理结果:(页面渲染流程)
    1). 如果有异常,使用异常解析器处理异常,处理完还会返回ModelAndView
    2). 调用render进行页面渲染
    a. 视图解析器根据视图名得到视图对象
    b. 视图对象调用render方法
    3). 执行拦截器的afterCompletion

在这里插入图片描述

SpringMVC和Spring整合

整合的目标是为了分工明确

SpringMVC的配置文件就用来配置和网站转发逻辑以及网站功能有关的(视图解析器,文件上传解析器,直接AJAX…)
Spring的配置文件就用来配置和事务有关的(事务控制、数据源…),实际上放入 Spring 配置文件对应的 IOC 容器中的还有 Service 和 Dao

推荐的整合方法是:创建两个容器,各自独立
容器在web.xml中创建

容器创建

** Spring容器 **
使用listener来管理spring ioc容器的创建销毁

<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>classpath:spring.xml</param-value>
</context-param>

<listener>
	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

** SpringMVC容器 **
在创建了前端控制器、视图解析器后,即创建了SpringMVC容器

<!-- 前端控制器 -->
<servlet>
	<servlet-name>dispatcher</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<!-- 
				servlet启动加载,servlet原本是第一次访问创建对象
				load-on-startup:服务器启动的时候创建对象,值越小优先级越高,越先创建对象 
			-->

			<!-- contextConfigLocation:指定springmvc配置文件位置 -->
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:springContext.xml</param-value>
			
		</init-param>
		<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
	<servlet-name>dispatcher</servlet-name>
	<url-pattern>/</url-pattern>
</servlet-mapping>


<!-- 字符编码 -->
<filter>
	<filter-name>CharacterEncodingFilter</filter-name>
	<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
	<!-- 指定参数 -->
	<init-param>
		<param-name>encoding</param-name>
		<param-value>utf-8</param-value>
	</init-param>
	<init-param>
		<param-name>forceEncoding</param-name>
		<param-value>true</param-value>
	</init-param>
	
</filter>
<filter-mapping>
	<filter-name>CharacterEncodingFilter</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

容器扫描组件

如果在两个容器的配置文件中都直接扫描组件,就会导致同一组件被创建了两次,并且会影响事务控制
解决的办法是在配置文件的扫描标签中,规定只扫描哪些组件(context:include-filter)或排除哪些组件(context:exclude-filter)
例如springmvc只扫controller,spring扫描其他的

springmvc.xml

<!--
	springmvc容器只扫描@Controller或@ControllerAdvice注解了的组件
-->
<context:component-scan base-package="com.jax" use-default-filters="false">
	<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
	<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>

<mvc:annotation-driven />

spring.xml

<!--
	spring容器只扫描@Controller和@ControllerAdvice以外的组件
-->
<context:component-scan base-package="com.jax" use-default-filters="true">
	<context:exclude-filter type="annotation"  expression="org.springframework.stereotype.Controller" />
	<context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值