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

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

  1. @Override
  2. protected String[] determineUrlsForHandler(String beanName) {
  3. Class<?> beanClass = getApplicationContext().getType(beanName);
  4. //判断是不是支持的类型
  5. if (isEligibleForMapping(beanName, beanClass)) {
  6. //模板方法,在子类实现
  7. return buildUrlsForHandler(beanName, beanClass);
  8. }
  9. else {
  10. return null;
  11. }
  12. }

抽象方法buildUrlsForHandler

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

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

  1. public void setIncludeAnnotatedControllers(boolean includeAnnotatedControllers) {
  2. this.predicate = (includeAnnotatedControllers ?
  3. new AnnotationControllerTypePredicate() : new ControllerTypePredicate());
  4. }
  5.  
  6. public void setExcludedPackages(String... excludedPackages) {
  7. this.excludedPackages = (excludedPackages != null) ?
  8. new HashSet<String>(Arrays.asList(excludedPackages)) : new HashSet<String>();
  9. }
  10.  
  11. public void setExcludedClasses(Class<?>... excludedClasses) {
  12. this.excludedClasses = (excludedClasses != null) ?
  13. new HashSet<Class<?>>(Arrays.asList(excludedClasses)) : new HashSet<Class<?>>();
  14. }

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

  1. protected boolean isEligibleForMapping(String beanName, Class<?> beanClass) {
  2. if (beanClass == null) {
  3. if (logger.isDebugEnabled()) {
  4. logger.debug("Excluding controller bean '" + beanName + "' from class name mapping " +
  5. "because its bean type could not be determined");
  6. }
  7. return false;
  8. }
  9. if (this.excludedClasses.contains(beanClass)) {
  10. if (logger.isDebugEnabled()) {
  11. logger.debug("Excluding controller bean '" + beanName + "' from class name mapping " +
  12. "because its bean class is explicitly excluded: " + beanClass.getName());
  13. }
  14. return false;
  15. }
  16. String beanClassName = beanClass.getName();
  17. for (String packageName : this.excludedPackages) {
  18. if (beanClassName.startsWith(packageName)) {
  19. if (logger.isDebugEnabled()) {
  20. logger.debug("Excluding controller bean '" + beanName + "' from class name mapping " +
  21. "because its bean class is defined in an excluded package: " + beanClass.getName());
  22. }
  23. return false;
  24. }
  25. }
  26. //
  27. return isControllerType(beanClass);
  28. }

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

AbstractControllerUrlHandlerMapping完整源码如下:

  1. public abstract class AbstractControllerUrlHandlerMapping extends AbstractDetectingUrlHandlerMapping {
  2.  
  3. private ControllerTypePredicate predicate = new AnnotationControllerTypePredicate();
  4.  
  5. private Set<String> excludedPackages = Collections.singleton("org.springframework.web.servlet.mvc");
  6.  
  7. private Set<Class<?>> excludedClasses = Collections.emptySet();
  8.  
  9. public void setIncludeAnnotatedControllers(boolean includeAnnotatedControllers) {
  10. this.predicate = (includeAnnotatedControllers ?
  11. new AnnotationControllerTypePredicate() : new ControllerTypePredicate());
  12. }
  13.  
  14. public void setExcludedPackages(String... excludedPackages) {
  15. this.excludedPackages = (excludedPackages != null) ?
  16. new HashSet<String>(Arrays.asList(excludedPackages)) : new HashSet<String>();
  17. }
  18.  
  19. public void setExcludedClasses(Class<?>... excludedClasses) {
  20. this.excludedClasses = (excludedClasses != null) ?
  21. new HashSet<Class<?>>(Arrays.asList(excludedClasses)) : new HashSet<Class<?>>();
  22. }
  23.  
  24. @Override
  25. protected String[] determineUrlsForHandler(String beanName) {
  26. Class<?> beanClass = getApplicationContext().getType(beanName);
  27. //判断是不是支持的类型
  28. if (isEligibleForMapping(beanName, beanClass)) {
  29. //模板方法,在子类实现
  30. return buildUrlsForHandler(beanName, beanClass);
  31. }
  32. else {
  33. return null;
  34. }
  35. }
  36.  
  37. protected boolean isEligibleForMapping(String beanName, Class<?> beanClass) {
  38. if (beanClass == null) {
  39. if (logger.isDebugEnabled()) {
  40. logger.debug("Excluding controller bean '" + beanName + "' from class name mapping " +
  41. "because its bean type could not be determined");
  42. }
  43. return false;
  44. }
  45. if (this.excludedClasses.contains(beanClass)) {
  46. if (logger.isDebugEnabled()) {
  47. logger.debug("Excluding controller bean '" + beanName + "' from class name mapping " +
  48. "because its bean class is explicitly excluded: " + beanClass.getName());
  49. }
  50. return false;
  51. }
  52. String beanClassName = beanClass.getName();
  53. for (String packageName : this.excludedPackages) {
  54. if (beanClassName.startsWith(packageName)) {
  55. if (logger.isDebugEnabled()) {
  56. logger.debug("Excluding controller bean '" + beanName + "' from class name mapping " +
  57. "because its bean class is defined in an excluded package: " + beanClass.getName());
  58. }
  59. return false;
  60. }
  61. }
  62. //
  63. return isControllerType(beanClass);
  64. }
  65.  
  66. //判断是否实现了Controller接口或者使用了@Controller
  67. protected boolean isControllerType(Class<?> beanClass) {
  68. return this.predicate.isControllerType(beanClass);
  69. }
  70.  
  71. protected boolean isMultiActionControllerType(Class<?> beanClass) {
  72. return this.predicate.isMultiActionControllerType(beanClass);
  73. }
  74.  
  75. protected abstract String[] buildUrlsForHandler(String beanName, Class<?> beanClass);
  76.  
  77. }

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. iOS masonry 不规则tagView布局 并自适应高度

    在搜索页面经常会有不规则的tag出现,这种tagView要有点击事件,单个tagView可以设置文字颜色,宽度不固定根据内容自适应,高度固定,数量不固定.总高度就不固定.最近对于masonry的使用又 ...

  2. CSS禁止输入之readonly VS disable

    Readonly只针对input(text / password)和textarea有效,而disabled对于所有的表单元素都有效,包括select, radio, checkbox, button ...

  3. 设计APP时我们该怎么做

    不得不承认,手机APP已经渗透到我们的生活中,根据数据统计,人们每天平均有3.9个小时是花费在手机APP的使用上的,可以预见,手机APP正在改变我们的生活.手机APP受到人们的欢迎,很多商家也看到了其 ...

  4. [LeetCode] Parse Lisp Expression 解析Lisp表达式

    You are given a string expression representing a Lisp-like expression to return the integer value of ...

  5. SocketServer源码学习(二)

    SocketServer 中非常重要的两个基类就是:BaseServer 和 BaseRequestHandler在SocketServer 中也提供了对TCP以及UDP的高级封装,这次我们主要通过分 ...

  6. [SCOI 2010]传送带

    Description 题库链接 在一个 \(2\) 维平面上有两条传送带,每一条传送带可以看成是一条线段.两条传送带分别为线段 \(AB\) 和线段 \(CD\) .在 \(AB\) 上的移动速度为 ...

  7. Codeforces Round #460 D. Karen and Cards

    Description Karen just got home from the supermarket, and is getting ready to go to sleep. After tak ...

  8. Codeforces Round#432 简要题解

    来自FallDream的博客,未经允许,请勿转载,谢谢. Div2A 小判断题 Div2B 小判断题,合法的条件是|AB|=|BC|且三点不共线 Div1A 类比二维.三维空间,可以猜测n太大的时候没 ...

  9. Docker学习笔记【一】

    [本篇学习笔记来源于 Docker 从入门到实践] 1.什么事Docker?[What] Docker在容器的基础上,进行了进一步的封装,从文件系统.网络互联到进程隔离等,极大的简化了容器的创建和维护 ...

  10. mac下怎么删除隐藏文件比如 .Trashes文件

    U盘和移动硬盘接入Mac时会产生.Trashes,.Spotlight-V100,.fseventsd等文件 每插入Mac一次,都会检查是否有这些文件,如果没有,就会创建这些文件 特别是有时候,在文件 ...