上一篇博客springMVC源码分析--AbstractDetectingUrlHandlerMapping(五)中我们介绍了AbstractDetectingUrlHandlerMapping,其定义了一个抽象方法determineUrlsForHandler在子类AbstractControllerUrlHandlerMapping中实现。

子类中AbstractControllerUrlHandlerMapping中determineUrlsForHandler的实现如下,实现原理就是根据beanName从容器中获取bean,然后调用buildUrlsForHandler完成beanName和beanClass的对应关系,其具体实现还是在其子类中实现。

	@Override
	protected String[] determineUrlsForHandler(String beanName) {
		Class<?> beanClass = getApplicationContext().getType(beanName);
		//判断是不是支持的类型
		if (isEligibleForMapping(beanName, beanClass)) {
			//模板方法,在子类实现
			return buildUrlsForHandler(beanName, beanClass);
		}
		else {
			return null;
		}
	}

抽象方法buildUrlsForHandler

protected abstract String[] buildUrlsForHandler(String beanName, Class<?> beanClass);

除此之外AbstractControllerUrlHandlerMapping还提供了一些配置,用于排除掉一些包或者一些类,可以在配置中进行配置

public void setIncludeAnnotatedControllers(boolean includeAnnotatedControllers) {
		this.predicate = (includeAnnotatedControllers ?
				new AnnotationControllerTypePredicate() : new ControllerTypePredicate());
	}

	public void setExcludedPackages(String... excludedPackages) {
		this.excludedPackages = (excludedPackages != null) ?
				new HashSet<String>(Arrays.asList(excludedPackages)) : new HashSet<String>();
	}

	public void setExcludedClasses(Class<?>... excludedClasses) {
		this.excludedClasses = (excludedClasses != null) ?
				new HashSet<Class<?>>(Arrays.asList(excludedClasses)) : new HashSet<Class<?>>();
	}

判断beanName和beanClass是否已经配置排除对应关系。

protected boolean isEligibleForMapping(String beanName, Class<?> beanClass) {
		if (beanClass == null) {
			if (logger.isDebugEnabled()) {
				logger.debug("Excluding controller bean '" + beanName + "' from class name mapping " +
						"because its bean type could not be determined");
			}
			return false;
		}
		if (this.excludedClasses.contains(beanClass)) {
			if (logger.isDebugEnabled()) {
				logger.debug("Excluding controller bean '" + beanName + "' from class name mapping " +
						"because its bean class is explicitly excluded: " + beanClass.getName());
			}
			return false;
		}
		String beanClassName = beanClass.getName();
		for (String packageName : this.excludedPackages) {
			if (beanClassName.startsWith(packageName)) {
				if (logger.isDebugEnabled()) {
					logger.debug("Excluding controller bean '" + beanName + "' from class name mapping " +
							"because its bean class is defined in an excluded package: " + beanClass.getName());
				}
				return false;
			}
		}
		//
		return isControllerType(beanClass);
	}

总结:AbstractControllerUrlHandlerMapping的实现机制就是根据beanName从容器中获取实现类beanClass,同时beanName和beanClass的对应关系的操作是在其子类中完成实现的,同时AbstractControllerUrlHandlerMapping提供了一些配置用于排除一些类的关系。

AbstractControllerUrlHandlerMapping完整源码如下:

public abstract class AbstractControllerUrlHandlerMapping extends AbstractDetectingUrlHandlerMapping  {

	private ControllerTypePredicate predicate = new AnnotationControllerTypePredicate();

	private Set<String> excludedPackages = Collections.singleton("org.springframework.web.servlet.mvc");

	private Set<Class<?>> excludedClasses = Collections.emptySet();

	public void setIncludeAnnotatedControllers(boolean includeAnnotatedControllers) {
		this.predicate = (includeAnnotatedControllers ?
				new AnnotationControllerTypePredicate() : new ControllerTypePredicate());
	}

	public void setExcludedPackages(String... excludedPackages) {
		this.excludedPackages = (excludedPackages != null) ?
				new HashSet<String>(Arrays.asList(excludedPackages)) : new HashSet<String>();
	}

	public void setExcludedClasses(Class<?>... excludedClasses) {
		this.excludedClasses = (excludedClasses != null) ?
				new HashSet<Class<?>>(Arrays.asList(excludedClasses)) : new HashSet<Class<?>>();
	}

	@Override
	protected String[] determineUrlsForHandler(String beanName) {
		Class<?> beanClass = getApplicationContext().getType(beanName);
		//判断是不是支持的类型
		if (isEligibleForMapping(beanName, beanClass)) {
			//模板方法,在子类实现
			return buildUrlsForHandler(beanName, beanClass);
		}
		else {
			return null;
		}
	}

	protected boolean isEligibleForMapping(String beanName, Class<?> beanClass) {
		if (beanClass == null) {
			if (logger.isDebugEnabled()) {
				logger.debug("Excluding controller bean '" + beanName + "' from class name mapping " +
						"because its bean type could not be determined");
			}
			return false;
		}
		if (this.excludedClasses.contains(beanClass)) {
			if (logger.isDebugEnabled()) {
				logger.debug("Excluding controller bean '" + beanName + "' from class name mapping " +
						"because its bean class is explicitly excluded: " + beanClass.getName());
			}
			return false;
		}
		String beanClassName = beanClass.getName();
		for (String packageName : this.excludedPackages) {
			if (beanClassName.startsWith(packageName)) {
				if (logger.isDebugEnabled()) {
					logger.debug("Excluding controller bean '" + beanName + "' from class name mapping " +
							"because its bean class is defined in an excluded package: " + beanClass.getName());
				}
				return false;
			}
		}
		//
		return isControllerType(beanClass);
	}

	//判断是否实现了Controller接口或者使用了@Controller
	protected boolean isControllerType(Class<?> beanClass) {
		return this.predicate.isControllerType(beanClass);
	}

	protected boolean isMultiActionControllerType(Class<?> beanClass) {
		return this.predicate.isMultiActionControllerType(beanClass);
	}

	protected abstract String[] buildUrlsForHandler(String beanName, Class<?> beanClass);

}

springMVC源码分析--AbstractControllerUrlHandlerMapping(六)的更多相关文章

  1. springMVC源码分析--ControllerClassNameHandlerMapping(九)

    在上一篇博客springMVC源码分析--AbstractControllerUrlHandlerMapping(六)中我们介绍到AbstractControllerUrlHandlerMapping ...

  2. springMVC源码分析--ControllerBeanNameHandlerMapping(八)

    在上一篇博客springMVC源码分析--AbstractControllerUrlHandlerMapping(六)中我们介绍到AbstractControllerUrlHandlerMapping ...

  3. springMVC源码分析--异常处理机制HandlerExceptionResolver执行原理(二)

    上一篇博客springMVC源码分析--异常处理机制HandlerExceptionResolver简单示例(一)中我们简单地实现了一个异常处理实例,接下来我们要介绍一下HandlerExceptio ...

  4. 框架-springmvc源码分析(二)

    框架-springmvc源码分析(二) 参考: http://www.cnblogs.com/leftthen/p/5207787.html http://www.cnblogs.com/leftth ...

  5. 8、SpringMVC源码分析(3):分析ModelAndView的形成过程

    首先,我们还是从DispatcherServlet.doDispatch(HttpServletRequest request, HttpServletResponse response) throw ...

  6. 7、SpringMVC源码分析(2):分析HandlerAdapter.handle方法,了解handler方法的调用细节以及@ModelAttribute注解

    从上一篇 SpringMVC源码分析(1) 中我们了解到在DispatcherServlet.doDispatch方法中会通过 mv = ha.handle(processedRequest, res ...

  7. springMVC源码分析--ViewNameMethodReturnValueHandler返回值处理器(三)

    之前两篇博客springMVC源码分析--HandlerMethodReturnValueHandler返回值解析器(一)和springMVC源码分析--HandlerMethodReturnValu ...

  8. springMVC源码分析--HandlerMethodReturnValueHandlerComposite返回值解析器集合(二)

    在上一篇博客springMVC源码分析--HandlerMethodReturnValueHandler返回值解析器(一)我们介绍了返回值解析器HandlerMethodReturnValueHand ...

  9. springMVC源码分析--RequestParamMethodArgumentResolver参数解析器(三)

    之前两篇博客springMVC源码分析--HandlerMethodArgumentResolver参数解析器(一)和springMVC源码解析--HandlerMethodArgumentResol ...

随机推荐

  1. [LeetCode] Judge Route Circle 判断路线绕圈

    Initially, there is a Robot at position (0, 0). Given a sequence of its moves, judge if this robot m ...

  2. python 云打码 hhtp接口

    import http.client, mimetypes, urllib, json, time, requests ######################################## ...

  3. 实验吧_Guess Next Session&Once More(代码审计)

    Guess Next Session 看题目提示,是一道代码审计: <?php session_start(); if (isset ($_GET['password'])) { if ($_G ...

  4. discuz7.2 faq.php 注入漏洞分析

    写在前面的话:分析完整个漏洞,不得不感叹,发现漏洞的人真的好细心呀. 在分析整个漏洞之前,没看poc,然后就直接看faq.php 准备试试自己发现漏洞的能力,但是分析完一整个php,也是卡在 in() ...

  5. PHPCMS某处设计缺陷可致authkey泄露

    在分析几个phpcms的漏洞就换分析其他的,换换口味. 漏洞来源:http://wooyun.jozxing.cc/static/bugs/wooyun-2015-0106892.html swfup ...

  6. [JSOI2007]字符加密

    题目描述 喜欢钻研问题的JS 同学,最近又迷上了对加密方法的思考.一天,他突然想出了一种他认为是终极的加密办法:把需要加密的信息排成一圈,显然,它们有很多种不同的读法. 例如‘JSOI07’,可以读作 ...

  7. 计蒜客NOIP2017提高组模拟赛(三)day1

    火山喷发 火山喷发对所有附近的生物具有毁灭性的影响.在本题中,我们希望用数值来模拟这一过程. 在环境里有 n 个生物分别具有 A​1​​,A​2​​,⋯,A​n​​点生命值,一次火山喷发总计 MM 轮 ...

  8. 数据权限管理中心 - 基于mybatis拦截器实现

    数据权限管理中心 由于公司大部分项目都是使用mybatis,也是使用mybatis的拦截器进行分页处理,所以技术上也直接选择从拦截器入手 需求场景 第一种场景:行级数据处理 原sql: select ...

  9. fatal error LNK1104: 无法打开文件“lua51.lib”

    今天学习C++与Lua通信,遇到了问题:fatal error LNK1104: 无法打开文件"lua51.lib" 开发环境: VS2012 cocos版本:cocos2d-x- ...

  10. TensorFlow-Bitcoin-Robot:一个基于 TensorFlow LSTM 模型的 Bitcoin 价格预测机器人

    简介 TensorFlow-Bitcoin-Robot:一个基于 TensorFlow LSTM 模型的 Bitcoin 价格预测机器人. 文章包括一下几个部分: 1.为什么要尝试做这个项目? 2.为 ...