这要从DefaultAnnotationHandlerMapping这个类说起,该类被@Component注释,该类被Spring IOC容器实例化之后,将会执行其initApplicationContext方法(该方法在其父类中得到实现)

主要的几个类的继承关系如上图,其中ApplicationObjectSupport是由SpringFrameWork提供的抽象类

上图是ApplicationObjectSupport类中的两个方法,该类实现了ApplicationContextAware接口,并且在setApplicationContext方法中,调用了上图中的initApplicationContext(context)方法做初始化工作(虽然实际上图的实现中什么也没做,但子类却获得了初始化的机会),而该方法又调用了抽象的initApplicationContext()方法,我的AbstractTransactionHandlerMapping类间接实现了ApplicationObjectSupport类,并且initApplicationContext()方法也在该类中得到了实现,这将使得容器完成启动后,AbstractTransactionHandlerMapping的子类对象,也就是我的DefaultAnnotationHandlerMapping对象的initApplicationContext()方法(该方法的具体代码在父类AbstractTransactionHandlerMapping中)将会得到Spring框架的调用

如上图,我的AbstractTransactionHandlerMapping类在initApplicationContext中调用了detectHandlers方法,该方法通过determineTranscodesForHandler(beanName)完成handler的查找,通过registerHandler(transcodes, beanName)完成handler的注册

所以以下分别就这两个步骤进行说明:

1.查找

首先,将Spring容器中所有的Singleton的BeanName取出来,放到String数组中

该数组的内容如上图。

如上图,determineTranscodesForHandler是在AbstractDetectingTransactionHandlerMapping的子类DefaultAnnotationHandlerMapping中实现的

该方法首先拿到容器,根据beanName取得其对应的Class对象,接下来AnnotationUtils.findAnnotation(handlerType, Controller.class)方法可以判断该类是否有Controller注解,如果没有那就说明没有符合要求的handler,如果有,自然要继续往该类的方法里面去找,哪些方法有我定义的@TransactionMapping方法,有了这些方法的Controller才能称之为一个SpringBank的handler

接下来determineTransactionForHandlerMethods里面的处理比较多余,实际上我并不需要去判断接口是否有注解,这里主要是参考并保留了SpringMVC的做法。对我来说,主要的逻辑就是取得Controller的类对象之后,判断一下里面哪些方法有@TransactionMapping注解,并且将注解里的Transaction对应的值取出来,放到一个Set中,最终这个Set的值类似于[Recharge, CreateOwner]

2.注册

当走到registerHandler这个方法时,其参数将会是这样:String[] transcodes = [CreateOwner, Recharge] ; String beanName = transactionController

这一步的处理已经很简单了,就是根据handler的名字取得容器中它的对象,然后以存在handlerMap中,最终handlerMap看起来将会和下面这样差不多:

handlerMap: {CreateOwner=com.springbank.portal.controller.TransactionController@651aed93, Recharge=com.springbank.portal.controller.TransactionController@651aed93}

springbank 开发日志 springbank是如何注册handler的的更多相关文章

  1. springbank 开发日志 springbank是如何执行一个handler的requestMapping对应的方法的

    占位 从dispatcher说起,方法doDispatch(Map request)的参数request是一个通过解析来报报文新城的map //获取HandlerExecutionChain,其中封装 ...

  2. springbank 开发日志 SpringMVC是如何找到handler找到对应的方法并执行的

    从DispatcherServlet说起,本文讨论的内容都是DispatcherServlet的doDispatch方法完成 mappedHandler是一个HandlerExecutionChain ...

  3. springbank 开发日志 Spring启动过程中对自定义标签的处理

    这篇随笔的许多知识来源于:http://www.importnew.com/19391.html 之所以会去看这些东东,主要是希望能够模仿spring mvc的处理流程,做出一套合理的交易处理流程. ...

  4. springbank 开发日志 阅读spring mvc的源代码真是受益良多

    决定模仿spring mvc的dispatcher->handlerMapping(return executorChain)->handler.execute 这样的流程之后,就开始看s ...

  5. SpringBank 开发日志 Mybatis 使用redis 作为二级缓存时,无法通过cacheEnabled=false 将其关闭

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC ...

  6. SpringBank 开发日志 一种简单的拦截器设计实现

    当交易由Action进入Service之前,需要根据不同的Service实际负责业务的不同,真正执行Service的业务逻辑之前,做一些检查工作.这样的拦截器应该是基于配置的,与Service关联起来 ...

  7. SpringBank 开发日志 使用maven构建dubbo服务的可执行jar包

    写这篇日志的时候,我已经完成了这个目标,并且中间经历了一次面试.现在回过头看,已经觉得印象不那么深刻了,果然还是一边思考,一边记录这样最好.但我还是严格要求自己,从新做了梳理,对相关配置进行了整理和说 ...

  8. SpringBank 开发日志 重新设计Action调用Service的参数传递 使用泛型解决类型转换问题

    之前想的比较简单,请求到达controller的时候,传给action的参数没有经过任何封装,就是一个Map.然后action再调用service的时候,传递的参数也是map @Controller ...

  9. springbank 开发日志 一次因为多线程问题导致的applicationContext.getBean()阻塞

    几天前遇到的这个问题.由于交易是配置的,不同的交易是同一个类的不同实例,所以不可能提前将其以@autowired类似的方式注入到需要的类中 <op:transaction id="Re ...

随机推荐

  1. idea_2018.1.5版本的激活使用

    1:步骤help中找到register,然后按如下截图操作 注册码: K71U8DBPNE-eyJsaWNlbnNlSWQiOiJLNzFVOERCUE5FIiwibGljZW5zZWVOYW1lIj ...

  2. 使用 Parallel LINQ 进行数据分页

    a)   第一种[耗时11~18s],这种查询方式并不是很优化,但是目前也没有想到更好的方式,除了创建一张中间表,是不是可以使用[全文索引]? SELECT * FROM ( SELECT  ROW_ ...

  3. string中substr,find函数使用

    2.string函数 find:某子串的起始位(0开始),函数的第二个参数使用代表从该位开始的后缀 substr:1) x开始的连续y位 2) x开始的后缀 #include<bits/stdc ...

  4. C++内存管理(转)http://www.cnblogs.com/qiubole/archive/2008/03/07/1094770.html

    [导语] 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对C++的痛恨,但内存管理在C++中无处不 ...

  5. loadrunner函数解密之web_reg_save_param

    loadrunner工具的使用,最关键的在于3个地方: A:脚本的编写 B:场景设计 C:性能测试结果分析 其 中难度比较大的第一步是:编写脚本,有很多人对于loadrunner里面的各种函数使用的并 ...

  6. sqlite limit offset

    limit 0,20 表示从第1条开始取20条数据 limit 20 offset 2  表示从第2条开始取出20条数据

  7. I - Older Brother Gym - 101490I

    题目链接:https://cn.vjudge.net/problem/Gym-101490I 题目大意:给你一个整数,问你这个整数能不能表示成一个素数的k次方? 具体思路:对于每一个数,我们先判断他是 ...

  8. CXF2.7整合spring发布webservice,返回值类型是Map和List<Map>类型

    在昨天研究了发布CXF发布webservice之后想着将以前的项目发布webservice接口,可是怎么也发布不起来,服务启动失败,原来是自己的接口有返回值类型是Map. 研究了一番之后,发现: we ...

  9. 四、Logisitic Regssion练习(转载)

    转载:http://www.cnblogs.com/tornadomeet/archive/2013/03/16/2963919.html 牛顿法:http://blog.csdn.net/xp215 ...

  10. [转]数据对齐对CPU的影响

    [转]http://www.cnblogs.com/wuzhenbo/archive/2012/06/05/2537465.html 1.前言 在IBM开发社区上发现一篇叫'Data alignmen ...