springmvc source code learning 2

public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMapping implements InitializingBean

//Implements the InitializingBean interface
public void afterPropertiesSet() {
		initHandlerMethods ();
	}

	/**
	 * Scan beans in the ApplicationContext, detect and register handler methods.
	 * @see #isHandler(Class)
	 * @see #getMappingForMethod(Method, Class)
	 * @see #handlerMethodsInitialized(Map)
	 */
	protected void initHandlerMethods() {
		if (logger.isDebugEnabled()) {
			logger.debug("Looking for request mappings in application context: " + getApplicationContext());
		}

		String[] beanNames = (this.detectHandlerMethodsInAncestorContexts ?
				BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) :
				getApplicationContext().getBeanNamesForType(Object.class));

		for (String beanName: beanNames) {
			if (isHandler(getApplicationContext().getType(beanName))){
   //If it is annotated with @Controller @RequestMapping
				detectHandlerMethods(beanName);
			}
		}
		handlerMethodsInitialized(getHandlerMethods());
	}

protected void detectHandlerMethods(final Object handler) {
		Class<?> handlerType = (handler instanceof String) ?
				getApplicationContext().getType((String) handler) : handler.getClass();

		final Class<?> userType = ClassUtils.getUserClass(handlerType);

		Set<Method> methods = HandlerMethodSelector.selectMethods(userType, new MethodFilter() {
			public boolean matches(Method method) {
				return getMappingForMethod(method, userType) != null;
			}
		});

		for (Method method : methods) {
			T mapping = getMappingForMethod(method, userType);
			registerHandlerMethod(handler, method, mapping);
		}
	}

protected void registerHandlerMethod(Object handler, Method method, T mapping) {
		HandlerMethod newHandlerMethod = createHandlerMethod(handler, method);
		HandlerMethod oldHandlerMethod = handlerMethods.get(mapping);
		if (oldHandlerMethod != null && !oldHandlerMethod.equals(newHandlerMethod)) {
			throw new IllegalStateException("Ambiguous mapping found. Cannot map '" + newHandlerMethod.getBean()
					+ "' bean method \n" + newHandlerMethod + "\nto " + mapping + ": There is already '"
					+ oldHandlerMethod.getBean() + "' bean method\n" + oldHandlerMethod + " mapped.");
		}

		this.handlerMethods.put(mapping, newHandlerMethod);
		if (logger.isInfoEnabled()) {
			logger.info("Mapped \"" + mapping + "\" onto " + newHandlerMethod);
		}

		Set<String> patterns = getMappingPathPatterns(mapping);
		for (String pattern : patterns) {
			if (!getPathMatcher().isPattern(pattern)) {
				this.urlMap.add(pattern, mapping);
			}
		}
	}

 After registration , the url and corresponding class methods annotated with @Controller @RequestMapping are encapsulated into HandlerMethod objects and cached in the handlerMethods map  

private final Map<T, HandlerMethod> handlerMethods = new LinkedHashMap<T, HandlerMethod>();

The interceptor is defined in the initApplicationContext method (as mentioned earlier, the initApplicationContext method is called through the aware interface ), it will look for the bean container and encapsulate the interceptor into a MappedInterceptor object. cached in

mappedInterceptors中

private final List<MappedInterceptor> mappedInterceptors = new ArrayList<MappedInterceptor>();

After that, when a request comes, find the handlerMethod corresponding to the request url in the handlerMethods, and find the interceptor in the mappedInterceptors to form a HandlerExecutionChain object.

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327039679&siteId=291194637
Recommended