本网站(662p.com)打包出售,且带程序代码数据,662p.com域名,程序内核采用TP框架开发,需要联系扣扣:2360248666 /wx:lianweikj
精品域名一口价出售:1y1m.com(350元) ,6b7b.com(400元) , 5k5j.com(380元) , yayj.com(1800元), jiongzhun.com(1000元) , niuzen.com(2800元) , zennei.com(5000元)
需要联系扣扣:2360248666 /wx:lianweikj
SpringMVC源码之Handler注册、获取以及请求controller中方法
talkchan · 658浏览 · 发布于2020-11-19 +关注

总结

  1. 对requestMappingHandlerMapping进行initializeBean时register Handler

  2. http开始请求时,initHandlerMappings,DispatcherServlet 中handlerMappings赋值完成

  3. 最后在DispatcherServlet#doDispatch()中,用对应的HandlerAdapter和Handler通过反射去请求controller中方法

对requestMappingHandlerMapping进行initializeBean时register Handler

调用链:

AbstractApplicationContext#refresh() --> AbstractApplicationContext#finishBeanFactoryInitialization() --> DefaultListableBeanFactory#preInstantiateSingletons() --> AbstractBeanFactory#getBean() --> AbstractBeanFactory#doGetBean() --> AbstractAutowireCapableBeanFactory#createBean() --> AbstractAutowireCapableBeanFactory#doCreateBean() --> AbstractAutowireCapableBeanFactory#initializeBean() --> AbstractAutowireCapableBeanFactory#invokeInitMethods() --> RequestMappingHandlerMapping#afterPropertiesSet() --> AbstractHandlerMethodMapping#afterPropertiesSet() --> AbstractHandlerMethodMapping#initHandlerMethods() --> AbstractHandlerMethodMapping#processCandidateBean --> AbstractHandlerMethodMapping#detectHandlerMethods() --> RequestMappingHandlerMapping#registerHandlerMethod() --> AbstractHandlerMethodMapping#registerHandlerMethod()

在AbstractHandlerMethodMapping#initHandlerMethods()中先获取所有的beanName,再挑选出符合条件的进行处理

protected void initHandlerMethods() {    
//获取容器中所有beanName
	for (String beanName : getCandidateBeanNames()) {		
	if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {			
	processCandidateBean(beanName);
		}
	}	
	handlerMethodsInitialized(getHandlerMethods());
}

判断是Handler的才继续调用detectHandlerMethods方法

protected void processCandidateBean(String beanName) {
	Class<?> beanType = null;
    ......	if (beanType != null && isHandler(beanType)) {
		detectHandlerMethods(beanName);
	}
}

满足handler的条件是(RequestMappingHandlerMapping#isHandler()):@Controller或@RequestMapping进行注解

@Overrideprotected boolean isHandler(Class<?> beanType) {	
return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
			AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
}

满足条件的,进行注册
RequestMappingHandlerMapping#registerHandlerMethod()

@Overrideprotected void registerHandlerMethod(Object handler, Method method, RequestMappingInfo mapping) {	
super.registerHandlerMethod(handler, method, mapping);
	updateConsumesCondition(mapping, method);
}

AbstractHandlerMethodMapping#registerHandlerMethod()

protected void registerHandlerMethod(Object handler, Method method, T mapping) {	
this.mappingRegistry.register(mapping, handler, method);
}

完成注册。AbstractHandlerMethodMapping#register()

public void register(T mapping, Object handler, Method method) {	
this.readWriteLock.writeLock().lock();	try {
		HandlerMethod handlerMethod = createHandlerMethod(handler, method);
		validateMethodMapping(handlerMethod, mapping);		
		Set<String> directPaths = AbstractHandlerMethodMapping.this.getDirectPaths(mapping);		
		for (String path : directPaths) {			
		this.pathLookup.add(path, mapping);
		}		
		String name = null;		
		if (getNamingStrategy() != null) {
			name = getNamingStrategy().getName(handlerMethod, mapping);
			addMappingName(name, handlerMethod);
		}

		CorsConfiguration config = initCorsConfiguration(handler, method, mapping);		
		if (config != null) {
			config.validateAllowCredentials();			
			this.corsLookup.put(handlerMethod, config);
		}		this.registry.put(mapping, new MappingRegistration<>(mapping, handlerMethod, directPaths, name));
	}	finally {		
	this.readWriteLock.writeLock().unlock();
	}
}

initHandlerMappings

调用链:

Standardwrapper#initServlet() --> HttpServletBean#init() --> FrameworkServlet#initServletBean() --> FrameworkServlet#initWebApplicationContext() --> DispatcherServlet#onRefresh() --> DispatcherServlet#initStrategies() -->
DispatcherServlet#initHandlerMappings()

http请求时,先initHandlerMappings.
matchingBeans会存储获取到所有符合条件的,再给handlerMappings赋值

private void initHandlerMappings(ApplicationContext context) {	
this.handlerMappings = null;	
if (this.detectAllHandlerMappings) {		
// Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
		Map<String, HandlerMapping> matchingBeans =
				BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);		
				if (!matchingBeans.isEmpty()) {			
				this.handlerMappings = new ArrayList<>(matchingBeans.values());			
				// We keep HandlerMappings in sorted order.
			AnnotationAwareOrderComparator.sort(this.handlerMappings);
		}
	}
}

其中BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);会先调用AbstractApplicationContext#getBeansOfType(),再调用DefaultListableBeanFactory#getBeansOfType()

先获取beanName requestMappingHandlerMapping,再根据beanName(requestMappingHandlerMapping)从容器获取beanInstance。最后put到result中返回

@Override@SuppressWarnings("unchecked")public <T> Map<String, T> getBeansOfType(		
@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit) throws BeansException {    
//获取requestMappingHandlerMapping
	String[] beanNames = getBeanNamesForType(type, includeNonSingletons, allowEagerInit);	
	Map<String, T> result = CollectionUtils.newLinkedHashMap(beanNames.length);	
	for (String beanName : beanNames) {		
	try {		    ////再根据beanName(requestMappingHandlerMapping)从容器获取beanInstance
			Object beanInstance = getBean(beanName);			
			if (!(beanInstance instanceof NullBean)) {
				result.put(beanName, (T) beanInstance);
			}
		}
	......	return result;
}

从而在initHandlerMappings给handlerMappings赋值完成

this.handlerMappings = new ArrayList<>(matchingBeans.values());

doDispatch

获取当前请求的handler和HandlerAdapter

DispatcherServlet#doDispatch()

mappedHandler = getHandler(processedRequest);

DispatcherServlet#getHandler()

protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {	
if (this.handlerMappings != null) {		
for (HandlerMapping mapping : this.handlerMappings) {
			HandlerExecutionChain handler = mapping.getHandler(request);			
			if (handler != null) {				
			return handler;
			}
		}
	}	return null;
}

通过反射方式请求controller中方法:

// Actually invoke the handler.mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

doDispatch代码附录

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);			
// Determine handler for the current request.
			mappedHandler = getHandler(processedRequest);			
if (mappedHandler == null) {
				noHandlerFound(processedRequest, response);				
return;
			}			// Determine handler adapter for the current request.
			HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());			
// Process last-modified header, if supported by the handler.
			String method = request.getMethod();			
boolean isGet = "GET".equals(method);			
if (isGet || "HEAD".equals(method)) {
				long lastModified = ha.getLastModified(request, mappedHandler.getHandler());				
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {					
return;
				}
			}			
if (!mappedHandler.applyPreHandle(processedRequest, response)) {				
return;
			}			// Actually invoke the handler.
			mv = ha.handle(processedRequest, response, mappedHandler.getHandler());			
if (asyncManager.isConcurrentHandlingStarted()) {				return;
			}

			applyDefaultViewName(processedRequest, mv);
			mappedHandler.applyPostHandle(processedRequest, response, mv);
		}		catch (Exception ex) {
			dispatchException = ex;
		}		catch (Throwable err) {			
// As of 4.3, we're processing Errors thrown from handler methods as well,
			// making them available for @ExceptionHandler methods and other scenarios.
			dispatchException = new NestedServletException("Handler dispatch failed", err);
		}
		processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
	}	catch (Exception ex) {
		triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
	}	catch (Throwable err) {
		triggerAfterCompletion(processedRequest, response, mappedHandler,				
new NestedServletException("Handler processing failed", err));
	}	finally {		if (asyncManager.isConcurrentHandlingStarted()) {			
// Instead of postHandle and afterCompletion
			if (mappedHandler != null) {
				mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
			}
		}		else {			
// Clean up any resources used by a multipart request.
			if (multipartRequestParsed) {
				cleanupMultipart(processedRequest);
			}
		}
	}
}



相关推荐

PHP实现部分字符隐藏

沙雕mars · 1322浏览 · 2019-04-28 09:47:56
Java中ArrayList和LinkedList区别

kenrry1992 · 906浏览 · 2019-05-08 21:14:54
Tomcat 下载及安装配置

manongba · 966浏览 · 2019-05-13 21:03:56
JAVA变量介绍

manongba · 960浏览 · 2019-05-13 21:05:52
什么是SpringBoot

iamitnan · 1084浏览 · 2019-05-14 22:20:36
加载中

0评论

评论
大家好,我是一名专注技术开发的技术屌丝,有什么问题可以互相交流,一起学习进步,谢谢。
分类专栏
小鸟云服务器
扫码进入手机网页