springMVC源码分析--AbstractControllerUrlHandlerMapping(六)
上一篇博客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(六)的更多相关文章
- springMVC源码分析--ControllerClassNameHandlerMapping(九)
在上一篇博客springMVC源码分析--AbstractControllerUrlHandlerMapping(六)中我们介绍到AbstractControllerUrlHandlerMapping ...
- springMVC源码分析--ControllerBeanNameHandlerMapping(八)
在上一篇博客springMVC源码分析--AbstractControllerUrlHandlerMapping(六)中我们介绍到AbstractControllerUrlHandlerMapping ...
- springMVC源码分析--异常处理机制HandlerExceptionResolver执行原理(二)
上一篇博客springMVC源码分析--异常处理机制HandlerExceptionResolver简单示例(一)中我们简单地实现了一个异常处理实例,接下来我们要介绍一下HandlerExceptio ...
- 框架-springmvc源码分析(二)
框架-springmvc源码分析(二) 参考: http://www.cnblogs.com/leftthen/p/5207787.html http://www.cnblogs.com/leftth ...
- 8、SpringMVC源码分析(3):分析ModelAndView的形成过程
首先,我们还是从DispatcherServlet.doDispatch(HttpServletRequest request, HttpServletResponse response) throw ...
- 7、SpringMVC源码分析(2):分析HandlerAdapter.handle方法,了解handler方法的调用细节以及@ModelAttribute注解
从上一篇 SpringMVC源码分析(1) 中我们了解到在DispatcherServlet.doDispatch方法中会通过 mv = ha.handle(processedRequest, res ...
- springMVC源码分析--ViewNameMethodReturnValueHandler返回值处理器(三)
之前两篇博客springMVC源码分析--HandlerMethodReturnValueHandler返回值解析器(一)和springMVC源码分析--HandlerMethodReturnValu ...
- springMVC源码分析--HandlerMethodReturnValueHandlerComposite返回值解析器集合(二)
在上一篇博客springMVC源码分析--HandlerMethodReturnValueHandler返回值解析器(一)我们介绍了返回值解析器HandlerMethodReturnValueHand ...
- springMVC源码分析--RequestParamMethodArgumentResolver参数解析器(三)
之前两篇博客springMVC源码分析--HandlerMethodArgumentResolver参数解析器(一)和springMVC源码解析--HandlerMethodArgumentResol ...
随机推荐
- .NET MD5 加密
using System; using System.Security.Cryptography; using System.Text; namespace Md5Demo { /// <sum ...
- Java 嵌套类基础详解
目录 1. 什么是嵌套类? 2. 为什么要使用嵌套类? 3. 嵌套类的类型 4. 静态嵌套类 5. 非静态嵌套类 5.1 成员内部类 5.2 局部内部类 5.3 匿名内部类 6. 嵌套接口 1. 什么 ...
- JavaScript数据结构与算法(一) 栈的实现
TypeScript版本源码 class Stack { items = []; public push(element) { this.items.push(element); } public p ...
- 走在spring的路上。。。。
一些spring的概念理解: 1.为什么需要spring? spring与我们平时用的工厂模式最大的差别在于,工厂模式设计还需要单独去建一个工厂类并去维护它, 而spring可只通过配置文件便可创建并 ...
- 第一章 搭建一个通用的.net core项目框架
项目目标部署环境:CentOS 7+ 项目技术点:.netcore2.0 + Autofac +webAPI + NHibernate5.1 + mysql5.6 + nginx 开源地址:https ...
- [LeetCode] K Inverse Pairs Array K个翻转对数组
Given two integers n and k, find how many different arrays consist of numbers from 1 to n such that ...
- [LeetCode] Detect Capital 检测大写格式
Given a word, you need to judge whether the usage of capitals in it is right or not. We define the u ...
- 洛谷P3164 [CQOI2014]和谐矩阵
高斯消元,可以直接消的 #include<cstdio> #include<cstdlib> #include<algorithm> #include<cst ...
- [USACO12OPEN]书架Bookshelf
Description 当农夫约翰闲的没事干的时候,他喜欢坐下来看书.多年过去,他已经收集了 N 本书 (1 <= N <= 100,000), 他想造一个新的书架来装所有书. 每本书 i ...
- Codeforces Round #430 B. Gleb And Pizza
Gleb ordered pizza home. When the courier delivered the pizza, he was very upset, because several pi ...