Spring MVC之HandlerMap 初始化(RequestmappingHandlerMapping)
AbstractHandlerMethodMapping类实现了InitializingBean接口,在属性初始化完成后会调用afterPropertiesSet()方法,在该方法中调用initHandlerMethods();进行HandlerMethod初始化。
/** * 扫描ApplicationContext中的Bean,查找并注册 handlerMethod */ protected void initHandlerMethods() { if (logger.isDebugEnabled()) { logger.debug("Looking for request mappings in application context: " + getApplicationContext()); } //从ApplicationContext中获取所有Bean名称 String[] beanNames = (this.detectHandlerMethodsInAncestorContexts ? BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) : getApplicationContext().getBeanNamesForType(Object.class)); //遍历Bean for (String name : beanNames) { if (!name.startsWith(SCOPED_TARGET_NAME_PREFIX) && isHandler(getApplicationContext().getType(name))) { //从bean中查找handler method detectHandlerMethods(name); } } //handler method 初始化 handlerMethodsInitialized(getHandlerMethods()); }
/** * 从一个Handler中查找 handler method */ protected void detectHandlerMethods(final Object handler) { Class<?> handlerType = (handler instanceof String ? getApplicationContext().getType((String) handler) : handler.getClass()); final Map<Method, T> mappings = new IdentityHashMap<Method, T>(); //获取Class final Class<?> userType = ClassUtils.getUserClass(handlerType); Set<Method> methods = HandlerMethodSelector.selectMethods(userType, new MethodFilter() { @Override public boolean matches(Method method) { T mapping = getMappingForMethod(method, userType); if (mapping != null) { mappings.put(method, mapping); return true; } else { return false; } } }); //遍历所有handler method,并注册 for (Method method : methods) { registerHandlerMethod(handler, method, mappings.get(method)); } }
isHandler 在RequestMappingHandlerMapping 具体实现
/** * {@inheritDoc} * Expects a handler to have a type-level @{@link Controller} annotation. */ @Override protected boolean isHandler(Class<?> beanType) { return ((AnnotationUtils.findAnnotation(beanType, Controller.class) != null) || (AnnotationUtils.findAnnotation(beanType, RequestMapping.class) != null)); }