SpringMVC源码剖析2——处理器映射器

SpringMVC源码剖析2——处理器映射器

01.处理器映射器 HandlerMapping

一句话概括作用: 为 我 们 建 立 起 @RequestMapping 注 解 和 控 制 器 方 法 的 对 应 关 系 。

怎么去查看

第一步:

处理器映射器的实体类:
RequestMappingHandlerMapping   
父类  
RequestMappingInfoHandlerMapping
父类的父类
AbstractHandlerMethodMapping
父类的父类的父类
AbstractHandlerMapping

第二步:找到对应的方法,获取拦截的方法

 
[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
public Map<T, HandlerMethod> getHandlerMethods() {
   this.mappingRegistry.acquireReadLock();
   try {
      return Collections.unmodifiableMap(this.mappingRegistry.getMappings());
   }
   finally {
      this.mappingRegistry.releaseReadLock();
   }
}
 
getMappings()代码内容
public Map<T, HandlerMethod> getMappings() {
   return this.mappingLookup;
}


此处能看到一个无界HashMap,存储的是映射关系


那么什么时候存进去的呢?
在AbstractHandlerMethodMapping类中有如下代码:
扫描ApplicationContext中的bean,检测并注册处理程序方法。用来扫描bean的

 
[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
protected void initHandlerMethods() {
   if (logger.isDebugEnabled()) {
      logger.debug("Looking for request mappings in application context: " + getApplicationContext());
   }
   String[] beanNames = (this.detectHandlerMethodsInAncestorContexts ?
         BeanFactoryUtils.beanNamesForTypeIncludingAncestors(obtainApplicationContext(), Object.class) :
         obtainApplicationContext().getBeanNamesForType(Object.class));
 
 
   for (String beanName : beanNames) {
      if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {
         Class<?> beanType = null;
         try {
            beanType = obtainApplicationContext().getType(beanName);
         }
         catch (Throwable ex) {
            // An unresolvable bean type, probably from a lazy bean - let's ignore it.
            if (logger.isDebugEnabled()) {
               logger.debug("Could not resolve target class for bean with name '" + beanName + "'", ex);
            }
         }
         if (beanType != null && isHandler(beanType)) {
            detectHandlerMethods(beanName);
         }
      }
   }
   handlerMethodsInitialized(getHandlerMethods());
}


上述方法将扫描到的Colltroler类当做参数传递到下面的方法,通过反射获取.class字节码,然后再通过反射将方法和方法上面的路径找到存到map中
detectHandlerMethods(beanName);
[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
protected void detectHandlerMethods(final Object handler) {
   Class<?> handlerType = (handler instanceof String ?
         obtainApplicationContext().getType((String) handler) : handler.getClass());
 
 
   if (handlerType != null) {
      final Class<?> userType = ClassUtils.getUserClass(handlerType);
      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);
               }
            });
      if (logger.isDebugEnabled()) {
         logger.debug(methods.size() + " request handler methods found on " + userType + ": " + methods);
      }
      for (Map.Entry<Method, T> entry : methods.entrySet()) {
         Method invocableMethod = AopUtils.selectInvocableMethod(entry.getKey(), userType);
         T mapping = entry.getValue();
         registerHandlerMethod(handler, invocableMethod, mapping);
      }
   }
}


registerHandlerMethod(handler, invocableMethod, mapping);
注册处理程序方法及其唯一映射。在启动时调用
[Java] 纯文本查看 复制代码
?
1
2
3
protected void registerHandlerMethod(Object handler, Method method, T mapping) {
   this.mappingRegistry.register(mapping, handler, method);
}


先加锁,后将方法和映射放入Map中的
register(mapping, handler, method);
[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public void register(T mapping, Object handler, Method method) {
   this.readWriteLock.writeLock().lock();
   try {
      HandlerMethod handlerMethod = createHandlerMethod(handler, method);
      assertUniqueMethodMapping(handlerMethod, mapping);
 
 
      if (logger.isInfoEnabled()) {
         logger.info("Mapped \"" + mapping + "\" onto " + handlerMethod);
      }
      this.mappingLookup.put(mapping, handlerMethod);
 
 
      List<String> directUrls = getDirectUrls(mapping);
      for (String url : directUrls) {
         this.urlLookup.add(url, mapping);
      }
 
 
      String name = null;
      if (getNamingStrategy() != null) {
         name = getNamingStrategy().getName(handlerMethod, mapping);
         addMappingName(name, handlerMethod);
      }
 
 
      CorsConfiguration corsConfig = initCorsConfiguration(handler, method, mapping);
      if (corsConfig != null) {
         this.corsLookup.put(handlerMethod, corsConfig);
      }
 
 
      this.registry.put(mapping, new MappingRegistration<>(mapping, handlerMethod, directUrls, name));
   }
   finally {
      this.readWriteLock.writeLock().unlock();
   }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值