首页 > 编程语言 > 详细

Spring MVC之HandlerMap 初始化

时间:2015-01-02 02:05:08      阅读:675      评论:0      收藏:0      [点我收藏+]

?

???? DispatcherServlet请求处理请求的过程中,会发现getHandler实际上是调用AbstractUrlHandlerMapping.getHandlerInternal()。?通过对该段代码进行走读后发现,是通过handlermap.get(urlPath)获取匹配的handler的,那么该handlerMap是在什么时候进行初始化的呢?

?

/**
	 * Look up a handler for the URL path of the given request.
	 * @param request current HTTP request
	 * @return the handler instance, or <code>null</code> if none found
	 */
	@Override
	protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
		String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
		Object handler = lookupHandler(lookupPath, request);
		if (handler == null) {
			// We need to care for the default handler directly, since we need to
			// expose the PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE for it as well.
			Object rawHandler = null;
			if ("/".equals(lookupPath)) {
				rawHandler = getRootHandler();
			}
			if (rawHandler == null) {
				rawHandler = getDefaultHandler();
			}
			if (rawHandler != null) {
				// Bean name or resolved handler?
				if (rawHandler instanceof String) {
					String handlerName = (String) rawHandler;
					rawHandler = getApplicationContext().getBean(handlerName);
				}
				validateHandler(rawHandler, request);
				handler = buildPathExposingHandler(rawHandler, lookupPath, lookupPath, null);
			}
		}
		if (handler != null && logger.isDebugEnabled()) {
			logger.debug("Mapping [" + lookupPath + "] to " + handler);
		}
		else if (handler == null && logger.isTraceEnabled()) {
			logger.trace("No handler mapping found for [" + lookupPath + "]");
		}
		return handler;
	}

	/**
	 * Look up a handler instance for the given URL path.
	 * <p>Supports direct matches, e.g. a registered "/test" matches "/test",
	 * and various Ant-style pattern matches, e.g. a registered "/t*" matches
	 * both "/test" and "/team". For details, see the AntPathMatcher class.
	 * <p>Looks for the most exact pattern, where most exact is defined as
	 * the longest path pattern.
	 * @param urlPath URL the bean is mapped to
	 * @param request current HTTP request (to expose the path within the mapping to)
	 * @return the associated handler instance, or <code>null</code> if not found
	 * @see #exposePathWithinMapping
	 * @see org.springframework.util.AntPathMatcher
	 */
	protected Object lookupHandler(String urlPath, HttpServletRequest request) throws Exception {
		// Direct match?
		Object handler = this.handlerMap.get(urlPath);
		if (handler != null) {
			// Bean name or resolved handler?
			if (handler instanceof String) {
				String handlerName = (String) handler;
				handler = getApplicationContext().getBean(handlerName);
			}
			validateHandler(handler, request);
			return buildPathExposingHandler(handler, urlPath, urlPath, null);
		}
		// Pattern match?
		List<String> matchingPatterns = new ArrayList<String>();
		for (String registeredPattern : this.handlerMap.keySet()) {
			if (getPathMatcher().match(registeredPattern, urlPath)) {
				matchingPatterns.add(registeredPattern);
			}
		}
		String bestPatternMatch = null;
		Comparator<String> patternComparator = getPathMatcher().getPatternComparator(urlPath);
		if (!matchingPatterns.isEmpty()) {
			Collections.sort(matchingPatterns, patternComparator);
			if (logger.isDebugEnabled()) {
				logger.debug("Matching patterns for request [" + urlPath + "] are " + matchingPatterns);
			}
			bestPatternMatch = matchingPatterns.get(0);
		}
		if (bestPatternMatch != null) {
			handler = this.handlerMap.get(bestPatternMatch);
			// Bean name or resolved handler?
			if (handler instanceof String) {
				String handlerName = (String) handler;
				handler = getApplicationContext().getBean(handlerName);
			}
			validateHandler(handler, request);
			String pathWithinMapping = getPathMatcher().extractPathWithinPattern(bestPatternMatch, urlPath);

			// There might be multiple ‘best patterns‘, let‘s make sure we have the correct URI template variables
			// for all of them
			Map<String, String> uriTemplateVariables = new LinkedHashMap<String, String>();
			for (String matchingPattern : matchingPatterns) {
				if (patternComparator.compare(bestPatternMatch, matchingPattern) == 0) {
					uriTemplateVariables
							.putAll(getPathMatcher().extractUriTemplateVariables(matchingPattern, urlPath));
				}
			}
			if (logger.isDebugEnabled()) {
				logger.debug("URI Template variables for request [" + urlPath + "] are " + uriTemplateVariables);
			}
			return buildPathExposingHandler(handler, bestPatternMatch, pathWithinMapping, uriTemplateVariables);
		}
		// No handler found...
		return null;
	}

?

?

?

在服务的启动日志中有这样一段日志:

?

2015-01-01 21:42:38  [ localhost-startStop-1:522842 ] - [ DEBUG ]  Returning cached instance of singleton bean ‘org.springframework.web.servlet.handler.MappedInterceptor#0‘
2015-01-01 21:42:40  [ localhost-startStop-1:524680 ] - [ DEBUG ]  Looking for URL mappings in application context: WebApplicationContext for namespace ‘web-servlet‘: startup date [Thu Jan 01 21:34:51 CST 2015]; parent: Root WebApplicationContext
2015-01-01 21:42:40  [ localhost-startStop-1:524698 ] - [ DEBUG ]  Returning cached instance of singleton bean ‘bookController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524699 ] - [ INFO ]  Mapped URL path [/bookList.htm] onto handler ‘bookController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524699 ] - [ DEBUG ]  Returning cached instance of singleton bean ‘bookController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524699 ] - [ INFO ]  Mapped URL path [/addNewBook.htm] onto handler ‘bookController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524700 ] - [ DEBUG ]  Returning cached instance of singleton bean ‘bookController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524700 ] - [ INFO ]  Mapped URL path [/book.htm] onto handler ‘bookController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524701 ] - [ DEBUG ]  Returning cached instance of singleton bean ‘bookController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524701 ] - [ INFO ]  Mapped URL path [/deleteBook.htm] onto handler ‘bookController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524709 ] - [ DEBUG ]  Returning cached instance of singleton bean ‘downloadController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524710 ] - [ INFO ]  Mapped URL path [/download.htm] onto handler ‘downloadController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524720 ] - [ DEBUG ]  Returning cached instance of singleton bean ‘reservationController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524721 ] - [ INFO ]  Mapped URL path [/reservation.htm] onto handler ‘reservationController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524729 ] - [ DEBUG ]  Returning cached instance of singleton bean ‘restMemberController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524729 ] - [ INFO ]  Mapped URL path [/members] onto handler ‘restMemberController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524729 ] - [ DEBUG ]  Returning cached instance of singleton bean ‘restMemberController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524730 ] - [ INFO ]  Mapped URL path [/members.*] onto handler ‘restMemberController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524730 ] - [ DEBUG ]  Returning cached instance of singleton bean ‘restMemberController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524730 ] - [ INFO ]  Mapped URL path [/members/] onto handler ‘restMemberController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524730 ] - [ DEBUG ]  Returning cached instance of singleton bean ‘restMemberController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524731 ] - [ INFO ]  Mapped URL path [/members/{memberId}] onto handler ‘restMemberController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524731 ] - [ DEBUG ]  Returning cached instance of singleton bean ‘restMemberController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524731 ] - [ INFO ]  Mapped URL path [/members/{memberId}.*] onto handler ‘restMemberController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524732 ] - [ DEBUG ]  Returning cached instance of singleton bean ‘restMemberController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524732 ] - [ INFO ]  Mapped URL path [/members/{memberId}/] onto handler ‘restMemberController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524745 ] - [ DEBUG ]  Returning cached instance of singleton bean ‘testController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524746 ] - [ INFO ]  Mapped URL path [/exception.htm] onto handler ‘testController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524746 ] - [ DEBUG ]  Returning cached instance of singleton bean ‘testController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524746 ] - [ INFO ]  Mapped URL path [/test.json] onto handler ‘testController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524747 ] - [ DEBUG ]  Returning cached instance of singleton bean ‘testController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524747 ] - [ INFO ]  Mapped URL path [/exception.json] onto handler ‘testController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524748 ] - [ DEBUG ]  Returning cached instance of singleton bean ‘testController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524749 ] - [ INFO ]  Mapped URL path [/test.htm] onto handler ‘testController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524749 ] - [ DEBUG ]  Returning cached instance of singleton bean ‘testController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524749 ] - [ INFO ]  Mapped URL path [/handlingTime.htm] onto handler ‘testController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524759 ] - [ DEBUG ]  Returning cached instance of singleton bean ‘welcomeController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524760 ] - [ INFO ]  Mapped URL path [/locale.htm] onto handler ‘welcomeController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524760 ] - [ DEBUG ]  Returning cached instance of singleton bean ‘welcomeController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524761 ] - [ INFO ]  Root mapping to handler ‘welcomeController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524761 ] - [ DEBUG ]  Returning cached instance of singleton bean ‘welcomeController‘
2015-01-01 21:42:40  [ localhost-startStop-1:524761 ] - [ INFO ]  Mapped URL path [/index.htm] onto handler ‘welcomeController‘

?通过该段日志我们可以找到HandlerMap?的初始化是在初始化应用上下文的时候进行初始化的。具体就是AbstractDetectingUrlHandlerMapping.detectHandlers();

?

?

public abstract class AbstractDetectingUrlHandlerMapping extends AbstractUrlHandlerMapping {

	private boolean detectHandlersInAncestorContexts = false;


	/**
	 * Set whether to detect handler beans in ancestor ApplicationContexts.
	 * <p>Default is "false": Only handler beans in the current ApplicationContext
	 * will be detected, i.e. only in the context that this HandlerMapping itself
	 * is defined in (typically the current DispatcherServlet‘s context).
	 * <p>Switch this flag on to detect handler beans in ancestor contexts
	 * (typically the Spring root WebApplicationContext) as well.
	 */
	public void setDetectHandlersInAncestorContexts(boolean detectHandlersInAncestorContexts) {
		this.detectHandlersInAncestorContexts = detectHandlersInAncestorContexts;
	}


	/**
	 * Calls the {@link #detectHandlers()} method in addition to the
	 * superclass‘s initialization.
	 */
	@Override
	public void initApplicationContext() throws ApplicationContextException {
		super.initApplicationContext();
		detectHandlers();
	}

?

	/**
	 * Register all handlers found in the current ApplicationContext.
	 * <p>The actual URL determination for a handler is up to the concrete
	 * {@link #determineUrlsForHandler(String)} implementation. A bean for
	 * which no such URLs could be determined is simply not considered a handler.
	 * @throws org.springframework.beans.BeansException if the handler couldn‘t be registered
	 * @see #determineUrlsForHandler(String)
	 */
	protected void detectHandlers() throws BeansException {
		if (logger.isDebugEnabled()) {
			logger.debug("Looking for URL mappings in application context: " + getApplicationContext());
		}
		String[] beanNames = (this.detectHandlersInAncestorContexts ?
				BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) :
				getApplicationContext().getBeanNamesForType(Object.class));

		// Take any bean name that we can determine URLs for.
		for (String beanName : beanNames) {
			String[] urls = determineUrlsForHandler(beanName);
			if (!ObjectUtils.isEmpty(urls)) {
				// URL paths found: Let‘s consider it a handler.
				registerHandler(urls, beanName);
			}
			else {
				if (logger.isDebugEnabled()) {
					logger.debug("Rejected bean name ‘" + beanName + "‘: no URL paths identified");
				}
			}
		}
	}

?

?

Spring MVC之HandlerMap 初始化

原文:http://zhangwei-david.iteye.com/blog/2171726

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!