spring mvc 流程

从web.xml开始

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

	<!--Spring配置文件-->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:spring-config.xml</param-value>
	</context-param>

	<servlet>
		<servlet-name>mvc-test</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<!--SpringMVC配置文件-->
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:springmvc-config.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>mvc-test</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

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

</web-app>

抛开tomcat加载web.xml过程, 这里只看springmvc流程。
ContextLoaderListener 加载spring容器,也就是spring-config.xml,这里加载流程和spring流程一样,不做讨论。

public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
  @Override
	public void contextInitialized(ServletContextEvent event) {
		initWebApplicationContext(event.getServletContext());
	}
}

DispatcherServlet 加载springmvc配置,也就是springmvc-config.xml。

public class DispatcherServlet extends FrameworkServlet {
}
public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware {
	protected WebApplicationContext initWebApplicationContext() {
		//其它步骤省略, 只标识重要步骤
		configureAndRefreshWebApplicationContext(cwac);
	}
}
protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac) {
	wac.addApplicationListener(new SourceFilteringListener(wac, new ContextRefreshListener()));
}

可以看到发布ContextRefreshListener()监听器。
而AbstractApplicationContext方法finishRefresh()发布ContextRefreshedEvent事件,所以能被ContextRefreshListener监听(spring监听事件
ContextRefreshListener最终调用以下方法,开始springmvc流程。

	protected void initStrategies(ApplicationContext context) {
		initMultipartResolver(context);
		initLocaleResolver(context);
		initThemeResolver(context);
		initHandlerMappings(context);
		initHandlerAdapters(context);
		initHandlerExceptionResolvers(context);
		initRequestToViewNameTranslator(context);
		initViewResolvers(context);
		initFlashMapManager(context);
	}

这里是springmvc的九大组件,查看源码会最终实例化以下实例。

# 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.method.annotation.RequestMappingHandlerMapping,\
	org.springframework.web.servlet.function.support.RouterFunctionMapping

org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
	org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter,\
	org.springframework.web.servlet.function.support.HandlerFunctionAdapter


org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver,\
	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

LocaleResolver:国际化支持;
HandlerMapping:url和实例bean对应;
HandlerAdapter:实际执行适配器;
HandlerExceptionResolver:异常解析器。

springmvc 调用过程最终会调用DispatcherServlet#doDispatch这个方法。

找出要被处理的方法和对应的拦截器
找出适配器
拦截器前置执行
调用方法
拦截器后置执行
异常处理和拦截器afterCompletion方法执行
doDispatch
HandlerExecutionChain mappedHandler = getHandler(processedRequest);
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
mappedHandler.applyPreHandle(processedRequest, response)
ha.handle
mappedHandler.applyPostHandle(processedRequest, response, mv)
processDispatchResult

调用方法, 这里主要以处理注解的RequestMappingHandlerAdapter流程为例。

找到被@InitBinder注解修饰的方法
找到被@ModelAttribute注解修饰的方法
包装将要被执行的方法
解析以上两个注解,并放入mavContainer中, 给以后数据绑定使用
执行具体方法调用
invokeHandlerMethod
WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
modelFactory.initModel(webRequest, mavContainer, invocableMethod);
invocableMethod.invokeAndHandle(webRequest, mavContainer);

执行具体方法调用的逻辑

  1. 参数绑定(参数绑定处理器)
  2. 返回值处理(返回值处理器)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值