SpringMVC如何装载Controller的方法

启动时如何运行

  • 启动时会找到RequestMappingHandlerMapping的afterPropertiesSet运行
  • 因为RequestMappingHandlerMapping实现InitializingBean接口,会在bean初始化调用afterPropertiesSet方法,具体源码如下:
// 1
public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMapping ...{
  public void afterPropertiesSet() {
        this.config = new BuilderConfiguration();
        this.config.setUrlPathHelper(this.getUrlPathHelper());
        this.config.setPathMatcher(this.getPathMatcher());
        this.config.setSuffixPatternMatch(this.useSuffixPatternMatch);
        this.config.setTrailingSlashMatch(this.useTrailingSlashMatch);
        this.config.setRegisteredSuffixPatternMatch(this.useRegisteredSuffixPatternMatch);
        this.config.setContentNegotiationManager(this.getContentNegotiationManager());
        super.afterPropertiesSet();
    }
    }      
// 2
public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMethodMapping<RequestMappingInfo>
// 3
public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMapping implements InitializingBean 
  • bean是放到哪里的,具体见AbstractHandlerMethodMapping源码:
//1
 public void afterPropertiesSet() {
        this.initHandlerMethods();
    }
//2
protected void initHandlerMethods() {
    String[] var1 = this.getCandidateBeanNames();
    int var2 = var1.length;
    for(int var3 = 0; var3 < var2; ++var3) {
        String beanName = var1[var3];
        if (!beanName.startsWith("scopedTarget.")) {
            this.processCandidateBean(beanName);
        }
    }
    this.handlerMethodsInitialized(this.getHandlerMethods());
}
//3
protected void processCandidateBean(String beanName) {
       Class beanType = null;
       try {
           beanType = this.obtainApplicationContext().getType(beanName);
       } catch (Throwable var4) {
           if (this.logger.isTraceEnabled()) {
               this.logger.trace("Could not resolve type for bean '" + beanName + "'", var4);
           }
       }
       if (beanType != null && this.isHandler(beanType)) {
           this.detectHandlerMethods(beanName);
       }
   }
   //4
  protected void detectHandlerMethods(Object handler) {
      Class<?> handlerType = handler instanceof String ? this.obtainApplicationContext().getType((String)handler) : handler.getClass();
      if (handlerType != null) {
          Class<?> userType = ClassUtils.getUserClass(handlerType);
          Map<Method, T> methods = MethodIntrospector.selectMethods(userType, (method) -> {
              try {
                  return this.getMappingForMethod(method, userType);
              } catch (Throwable var4) {
                  throw new IllegalStateException("Invalid mapping on handler class [" + userType.getName() + "]: " + method, var4);
              }
          });
          if (this.logger.isTraceEnabled()) {
              this.logger.trace(this.formatMappings(userType, methods));
          }
          methods.forEach((method, mapping) -> {
              Method invocableMethod = AopUtils.selectInvocableMethod(method, userType);
              this.registerHandlerMethod(handler, invocableMethod, mapping);
          });
      }
  }
  //5
protected void registerHandlerMethod(Object handler, Method method, T mapping) {
	   //6
       this.mappingRegistry.register(mapping, handler, method);
 }
private final AbstractHandlerMethodMapping<T>.MappingRegistry mappingRegistry = new AbstractHandlerMethodMapping.MappingRegistry();
  1. 初始化调用afterPropertiesSet
  2. 调用initHandlerMethods
  3. 调用processCandidateBean
  4. 调用detectHandlerMethods
  5. 调用registerHandlerMethod
  6. 最终this.mappingRegistry.register(mapping, handler, method);
  • 下面再看看AbstractHandlerMethodMapping的register方法,传递的参数如图:
    在这里插入图片描述
public void register(T mapping, Object handler, Method method) {
    this.readWriteLock.writeLock().lock();//写锁
    try {
        HandlerMethod handlerMethod = AbstractHandlerMethodMapping.this.createHandlerMethod(handler, method);
        this.assertUniqueMethodMapping(handlerMethod, mapping);
        this.mappingLookup.put(mapping, handlerMethod);//方法类型和url加入到mappingLookup
        List<String> directUrls = this.getDirectUrls(mapping);
        Iterator var6 = directUrls.iterator();
        while(var6.hasNext()) {
            String url = (String)var6.next();
            this.urlLookup.add(url, mapping);
        }
        String name = null;
        if (AbstractHandlerMethodMapping.this.getNamingStrategy() != null) {
            name = AbstractHandlerMethodMapping.this.getNamingStrategy().getName(handlerMethod, mapping);
            this.addMappingName(name, handlerMethod);
        }
        CorsConfiguration corsConfig = AbstractHandlerMethodMapping.this.initCorsConfiguration(handler, method, mapping);
        if (corsConfig != null) {
            this.corsLookup.put(handlerMethod, corsConfig);
        }
        this.registry.put(mapping, new AbstractHandlerMethodMapping.MappingRegistration(mapping, handlerMethod, directUrls, name));
    } finally {
        this.readWriteLock.writeLock().unlock();//解锁
    }
}
  • 所有Controller下方法相关的均的均存入到了MappingRegistry 中,可以自行debug。
 class MappingRegistry {
        private final Map<T, AbstractHandlerMethodMapping.MappingRegistration<T>> registry = new HashMap();
        private final Map<T, HandlerMethod> mappingLookup = new LinkedHashMap();
        private final MultiValueMap<String, T> urlLookup = new LinkedMultiValueMap();
        private final Map<String, List<HandlerMethod>> nameLookup = new ConcurrentHashMap();
        private final Map<HandlerMethod, CorsConfiguration> corsLookup = new ConcurrentHashMap();
        private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();

如:
在这里插入图片描述
参考

猜你喜欢

转载自blog.csdn.net/i6725545/article/details/87712911