大连cms建站模板,电脑培训班价目表,建设银行开通网站查询密码,网站设计参考文献SpringMVC九大内置组件之HandlerMapping处理器映射器-AbstractHandlerMethodMapping类以及子类RequestMappingHandlerMapping如何将Controller修饰的注解类以及类下被注解RequestMapping修饰的方法存储到处理器映射器中。 从RequestMappingHandlerMapping寻找: AbstractHandle…SpringMVC九大内置组件之HandlerMapping处理器映射器-AbstractHandlerMethodMapping类以及子类RequestMappingHandlerMapping如何将Controller修饰的注解类以及类下被注解RequestMapping修饰的方法存储到处理器映射器中。 从RequestMappingHandlerMapping寻找: AbstractHandlerMethodMapping类的mappingRegistry什么时候赋值的呢
AbstractHandlerMethodMapping类以及子类RequestMappingHandlerMapping的类关系图如下实现了InitializingBean接口那么该映射器在SpringMVC容器中进行9大组件初始化的时候肯定会调用该afterPropertiesSet方法。 调用链路如下在启动项目的时候先进行Spring父容器的刷新然后进行SpringMVC子容器的刷新在子容器中监听器会进行调用9大组件初始化代码(initStrategies)。初始化 HandlerMapping:映射器(initHandlerMappings,配置文件没有配置就获取默认的实例化属性填充之后进行初始化的设置调用InitializingBean接口。开始完成Controller注解进行方法和controller的映射关系便于在后续进行http接口调用的时候根据请求路径找到方法名从而获取到对行的controller类去执行方法
InitializingBean接口的afterPropertiesSet方法:200, RequestMappingHandlerMapping (org.springframework.web.servlet.mvc.method.annotation)
invokeInitMethods:2352, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
调用初始化方法先调用bean的InitializingBean接口方法后调用bean的自定义初始化方法 initializeBean:2261, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:736, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:630, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:361, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createDefaultStrategy:957, DispatcherServlet (org.springframework.web.servlet)
getDefaultStrategies:925, DispatcherServlet (org.springframework.web.servlet)
初始化 HandlerMapping:映射器用来将对应的request跟controller进行对应initHandlerMappings:657, DispatcherServlet (org.springframework.web.servlet)
initStrategies:529, DispatcherServlet (org.springframework.web.servlet)
onRefresh:514, DispatcherServlet (org.springframework.web.servlet)
onApplicationEvent:901, FrameworkServlet (org.springframework.web.servlet)
onApplicationEvent:1277, FrameworkServlet$ContextRefreshListener (org.springframework.web.servlet)
onApplicationEvent:1273, FrameworkServlet$ContextRefreshListener (org.springframework.web.servlet)
onApplicationEvent:64, GenericApplicationListenerAdapter (org.springframework.context.event)
onApplicationEventInternal:109, SourceFilteringListener (org.springframework.context.event)
onApplicationEvent:73, SourceFilteringListener (org.springframework.context.event)
doInvokeListener:215, SimpleApplicationEventMulticaster (org.springframework.context.event)
invokeListener:202, SimpleApplicationEventMulticaster (org.springframework.context.event)
multicastEvent:164, SimpleApplicationEventMulticaster (org.springframework.context.event)
publishEvent:440, AbstractApplicationContext (org.springframework.context.support)
publishEvent:379, AbstractApplicationContext (org.springframework.context.support)
finishRefresh:1053, AbstractApplicationContext (org.springframework.context.support)
refresh:618, AbstractApplicationContext (org.springframework.context.support)
configureAndRefreshWebApplicationContext:759, FrameworkServlet (org.springframework.web.servlet)
createWebApplicationContext:715, FrameworkServlet (org.springframework.web.servlet)
createWebApplicationContext:773, FrameworkServlet (org.springframework.web.servlet)
initWebApplicationContext:625, FrameworkServlet (org.springframework.web.servlet)
initServletBean:536, FrameworkServlet (org.springframework.web.servlet)
init:185, HttpServletBean (org.springframework.web.servlet)
init:158, GenericServlet (javax.servlet)
initServlet:1164, StandardWrapper (org.apache.catalina.core)
loadServlet:1117, StandardWrapper (org.apache.catalina.core)
load:1010, StandardWrapper (org.apache.catalina.core)
loadOnStartup:4957, StandardContext (org.apache.catalina.core)
startInternal:5264, StandardContext (org.apache.catalina.core)
start:183, LifecycleBase (org.apache.catalina.util)
addChildInternal:726, ContainerBase (org.apache.catalina.core)
addChild:698, ContainerBase (org.apache.catalina.core)
addChild:696, StandardHost (org.apache.catalina.core)
manageApp:1783, HostConfig (org.apache.catalina.startup)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
invoke:293, BaseModelMBean (org.apache.tomcat.util.modeler)
invoke:819, DefaultMBeanServerInterceptor (com.sun.jmx.interceptor)
invoke:801, JmxMBeanServer (com.sun.jmx.mbeanserver)
createStandardContext:460, MBeanFactory (org.apache.catalina.mbeans)
createStandardContext:408, MBeanFactory (org.apache.catalina.mbeans)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
invoke:293, BaseModelMBean (org.apache.tomcat.util.modeler)
invoke:819, DefaultMBeanServerInterceptor (com.sun.jmx.interceptor)
invoke:801, JmxMBeanServer (com.sun.jmx.mbeanserver)
invoke:468, MBeanServerAccessController (com.sun.jmx.remote.security)
doOperation:1468, RMIConnectionImpl (javax.management.remote.rmi)
access$300:76, RMIConnectionImpl (javax.management.remote.rmi)
run:1309, RMIConnectionImpl$PrivilegedOperation (javax.management.remote.rmi)
doPrivileged:-1, AccessController (java.security)
doPrivilegedOperation:1408, RMIConnectionImpl (javax.management.remote.rmi)
invoke:829, RMIConnectionImpl (javax.management.remote.rmi)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
dispatch:346, UnicastServerRef (sun.rmi.server)
run:200, Transport$1 (sun.rmi.transport)
run:197, Transport$1 (sun.rmi.transport)
doPrivileged:-1, AccessController (java.security)
serviceCall:196, Transport (sun.rmi.transport)
handleMessages:568, TCPTransport (sun.rmi.transport.tcp)
run0:826, TCPTransport$ConnectionHandler (sun.rmi.transport.tcp)
lambda$run$0:683, TCPTransport$ConnectionHandler (sun.rmi.transport.tcp)
run:-1, 1316528462 (sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$25)
doPrivileged:-1, AccessController (java.security)
run:682, TCPTransport$ConnectionHandler (sun.rmi.transport.tcp)
runWorker:1142, ThreadPoolExecutor (java.util.concurrent)
run:617, ThreadPoolExecutor$Worker (java.util.concurrent)
run:748, Thread (java.lang)去父类AbstractHandlerMethodMapping类中去调用 在初始化时检测处理程序方法。 扫描ApplicationContext中的bean检测和注册处理程序方法 判断 Bean 是否为处理器例如有 Controller 或者 RequestMapping 注解 Overrideprotected boolean isHandler(Class? beanType) {// 判断是否有 Controller 或者 RequestMapping 的注解return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));}找到controller类上的方法去存储到处理器映射器中: /*** Uses method and type-level {link RequestMapping} annotations to create* the RequestMappingInfo.* return the created RequestMappingInfo, or {code null} if the method* does not have a {code RequestMapping} annotation.* see #getCustomMethodCondition(Method)* see #getCustomTypeCondition(Class)*/OverrideNullableprotected RequestMappingInfo getMappingForMethod(Method method, Class? handlerType) {// 基于方法上的 RequestMapping 注解创建 RequestMappingInfo 对象RequestMappingInfo info createRequestMappingInfo(method);if (info ! null) {// 基于类上的 RequestMapping 注解合并进去RequestMappingInfo typeInfo createRequestMappingInfo(handlerType);if (typeInfo ! null) {info typeInfo.combine(info);}// 如果有前缀则设置到 info 中String prefix getPathPrefix(handlerType);if (prefix ! null) {info RequestMappingInfo.paths(prefix).options(this.config).build().combine(info);}}return info;}/*** Delegates to {link #createRequestMappingInfo(RequestMapping, RequestCondition)},* supplying the appropriate custom {link RequestCondition} depending on whether* the supplied {code annotatedElement} is a class or method.* see #getCustomTypeCondition(Class)* see #getCustomMethodCondition(Method)*/Nullableprivate RequestMappingInfo createRequestMappingInfo(AnnotatedElement element) {// 获得 RequestMapping 注解RequestMapping requestMapping AnnotatedElementUtils.findMergedAnnotation(element, RequestMapping.class);// 获得自定义的条件。目前都是空方法可以无视RequestCondition? condition (element instanceof Class ?getCustomTypeCondition((Class?) element) : getCustomMethodCondition((Method) element));// 基于 RequestMapping 注解创建 RequestMappingInfo 对象return (requestMapping ! null ? createRequestMappingInfo(requestMapping, condition) : null);}getMappingForMethod方法中调用createRequestMappingInfo方法完成从类中筛选有RequestMapping注解修饰的方法存储到处理器映射器中
RequestMappingHandlerMapping的registerHandlerMethod
protected 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 /*** 释放读锁** Release the read lock after using getMappings and getMappingsByUrl.*/public void releaseReadLock() {this.readWriteLock.readLock().unlock();}public void register(T mapping, Object handler, Method method) {// Assert that the handler method is not a suspending one.if (KotlinDetector.isKotlinType(method.getDeclaringClass())) {Class?[] parameterTypes method.getParameterTypes();if ((parameterTypes.length 0) kotlin.coroutines.Continuation.equals(parameterTypes[parameterTypes.length - 1].getName())) {throw new IllegalStateException(Unsupported suspending handler method detected: method);}}// 获得写锁this.readWriteLock.writeLock().lock();try {// 创建HandlerMethod对象HandlerMethod handlerMethod createHandlerMethod(handler, method);// 校验当前mapping是否存在对应的HandlerMethod对象如果已存在但不是当前的handlerMethod对象则抛出异常validateMethodMapping(handlerMethod, mapping);// 将mapping与handlerMethod的映射关系保存至this.mappingLookupthis.mappingLookup.put(mapping, handlerMethod);// 获得mapping对应的普通URL数组ListString directUrls getDirectUrls(mapping);// 将url和mapping的映射关系保存至this.urlLookupfor (String url : directUrls) {this.urlLookup.add(url, mapping);}// 初始化nameLookupString name null;if (getNamingStrategy() ! null) {// 获得Mapping的名字name getNamingStrategy().getName(handlerMethod, mapping);// 将mapping的名字与HandlerMethod的映射关系保存至this.nameLookupaddMappingName(name, handlerMethod);}// 初始化CorsConfiguration配置对象CorsConfiguration corsConfig initCorsConfiguration(handler, method, mapping);if (corsConfig ! null) {this.corsLookup.put(handlerMethod, corsConfig);}// 创建MappingRegistration对象// 并与mapping映射添加到registry注册表中this.registry.put(mapping, new MappingRegistration(mapping, handlerMethod, directUrls, name));}finally {// 释放写锁this.readWriteLock.writeLock().unlock();}}submit方法对应的FlashMapController存在映射器了其他Controller修饰的注解处理过程一样。