SpringMVC及其HandlerMapping、HandlerInterceptor、HandlerAdapter等组件的原理解析

SpringMVC的原理

加载的过程

 关于加载,在SpringIOC的加载过程中,并不会直接将HandlerMapping等组件给加载进去,而是在第一次请求的时候,进行初始化

SpringMVC核心类,DispatcherServlet的类图

image


关于DispatcherServlet的初始化过程:由HttpServletBean调用init(),再由FrameworkServlet实现initServletBean(),最终由DispatcherServlet实现onRefresh(),并在其中加载初始化各个组件。

	protected void initStrategies(ApplicationContext context) {
		initMultipartResolver(context);//加载上传解析器
		initLocaleResolver(context);
		initThemeResolver(context);//
		initHandlerMappings(context);//加载初始化HandlerMapping
		initHandlerAdapters(context);//加载初始化HandlerAdapter
		initHandlerExceptionResolvers(context);//加载初始化HandlerException
		initRequestToViewNameTranslator(context);
		initViewResolvers(context);
		initFlashMapManager(context);
	}

HandlerMapping初始化过程

 通过SpringBean工厂获取已经加载了的HandlerMapping的实现类对象

	private void initHandlerMappings(ApplicationContext context) {
		this.handlerMappings = null;

		if (this.detectAllHandlerMappings) {
			// Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
			//通过SpringIOC获取已经加载了的HandlerMapping的实现类对象
			Map<String, HandlerMapping> matchingBeans =
					BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
		//省略。。。
	}

 在初始化的过程中,通过类型type从SpringIOC容器中去获取HandlerMapping的实现类
image
 SpringBoot默认加载了5个HandlerMapping的实现类:
RequestMappingHandlerMapping:通过@RequestMapping映射的路径寻找到对应方法的类
WelcomePageHandlerMapping:配置默认欢迎页时需要配置的类
BeanNameUrlHandlerMapping:和下面的SimplerUrlHandlerMapping类似,都是通过xml文件的方式配置url,将url与对应的Controller的方法进行绑定
SimpleUrlHandlerMapping:如上所说


 在SpringMVC初始化之前,SpringIOC加载RequestMappingHandlerMapping的时候,在AbstractAutowireCapableBeanFactory构建好对象,并进行初始化(initializeBean())的时候,将各个@RequestMapping对应的Controller方法映射的String地址给注册到RequestMappingHandlerMapping

	protected void detectHandlerMethods(Object handler) {
		//...
			Map<Method, T> methods = MethodIntrospector.selectMethods(userType,
					(MethodIntrospector.MetadataLookup<T>) method -> {
						try {
							return getMappingForMethod(method, userType);
						}
						catch (Throwable ex) {
							throw new IllegalStateException("Invalid mapping on handler class [" +
									userType.getName() + "]: " + method, ex);
						}
					});
			//...
			//
			methods.forEach((method, mapping) -> {
				Method invocableMethod = AopUtils.selectInvocableMethod(method, userType);
				registerHandlerMethod(handler, invocableMethod, mapping);
			});
		}
	}

	protected void registerHandlerMethod(Object handler, Method method, T mapping) {
		//将对应的url映射到对应的Controller方法上
		this.mappingRegistry.register(mapping, handler, method);
	}

HandlerInterceptor在加载的时候

HandlerInterceptor随着RequestMappingHandlerMapping在SpringIOC中创建对象的同时,进行加载与初始化

	protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		// 实例化对象
		BeanWrapper instanceWrapper = null;

		if (instanceWrapper == null) {
			//在实例化对象的包装器的时候,将HandlerInterceptor进行了加载与初始化
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		Object bean = instanceWrapper.getWrappedInstance();

		// 对实例对象初始化
		Object exposedObject = bean;
		try {
			populateBean(beanName, mbd, instanceWrapper);
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}


		//

		return exposedObject;
	}

HandlerAdapter在加载的时候

 和HandlerMapping的流程类似,都是现在SpringIOC中加载、初始化对象,然后在SpringMVC第一次请求来的时候,将HandlerAdapter的实现对象初始化到SpringMVC的上下文中。
HandlerAdapter的常见实现类:
image
RequestMappingHandlerAdapter:通过RequestMapping请求的处理器
HttpRequesthandlerAdapter:静态资源处理器
SimpleControllerHandlerAdapterController接口实现类的处理器,处理Controller实现类的请求
 ``

SpringMVC的工作流程

	protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
		HttpServletRequest processedRequest = request;
		HandlerExecutionChain mappedHandler = null;
		boolean multipartRequestParsed = false;

		WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

		try {
			ModelAndView mv = null;
			Exception dispatchException = null;

			try {
				processedRequest = checkMultipart(request);
				multipartRequestParsed = (processedRequest != request);

				//1.通过请求的url找到应该使用哪个HandlerMapping,并获取到HandlerMapping的HandlerExecutionChain
				//HandlerInterceptor就是在这里进行初始化的,每次请求来时,都会在HandlerExecutionChain对象中赋值
				mappedHandler = getHandler(processedRequest);

				//2.通过HandlerMethod找到其应该用哪个HandlerAdapter
				HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

				//3.执行HandlerInterptor中的preHandler
				if (!mappedHandler.applyPreHandle(processedRequest, response)) {
					return;
				}

				//4.通过HandlerAdapter调用Contoller中的具体方法,并返回ModelAndView
				//如果不返回ModelAndView,则直接响应用户了
				//在这里面,有HandlerAdapter决定了如果处理请求体、响应体
				mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

				if (asyncManager.isConcurrentHandlingStarted()) {
					return;
				}

				applyDefaultViewName(processedRequest, mv);
				//5.执行HandlerInterptor中的postHandler
				mappedHandler.applyPostHandle(processedRequest, response, mv);
			}
			catch (Exception ex) {
				dispatchException = ex;
			}

			processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
		}
	}

HandlerMapping在工作的时候

HandlerInterceptor在工作的时候

HandlerAdapter在工作的时候

posted on 2021-04-21 00:05  lyjlyjlyj  阅读(248)  评论(0编辑  收藏  举报

导航