springmvc中配置这个标签默认注册三个bean:RequestMappingHandlerMapping,RequestMappingHandlerAdapter,DefaultHandlerExceptionResolver
RequestMappingHandlerMapping
我们看它实现了InitializingBean 接口,所以在getBean()实例化它时会执行afterPropertiesSet()方法,来看该方法干了什么?
方法中实例化了一个BuilderConfiguration对象,并为该对象设置了一些路径抓取器,路径方法匹配器等。最后还需要调用父类的方法
父类只是调用了initHandlerMethods()方法,该方法很关键是将请求路径和方法匹配的
// 获得所有的beanName
// 遍历所有的beanName并获得type类型
// 判断类是否被@Controller或是@RequestMapping注释了,是执行detectHandlerMethods(beanName)方法
// 首先获得类型class,根据类的class获得一个Map,这个map的key是Method,value是RequestMappingInfo,后文详解#1
// 遍历map,获得Method和RequestMappingInfo,注册他们。后文详解#2
书接前文#1
selectMethods()方法中,根据类的class获得所有的方法,遍历方法执行doWith(Method method)方法
获得方法和RequestMappingInfo,将他们存到Map中返回,RequestMappingInfo是怎么获得的呢?我们马上来看
执行的是detectHandlerMethods()方法中的getMappingForMethod(method, userType)方法,该方法是一个抽象方法。RequestMappingHandlerMapping执行方法
// 创建方法的RequestMappingInfo,后文详解#1-1
// 创建类的RequestMappingInfo,该步骤和上一步如出一辙
// 将前两者结合,后文详解#1-2
书接前文#1-1
// 获得方法上的@RequestMapping注解的信息,根据注解创建RequestMappingInfo
这里使用了建造者模式创建,我们来看build()方法干了什么?
方法中关键的是PatternsRequestCondition对象,该对象的patterns属性保存了方法注解的路径值如 /app,创建了RequestMappingInfo返回
书接前文#1-2
方法中分别使用结合方法,然后重新创建一个返回,我们主要来看一下PatternsRequestCondition的方法
使用了AntPathMatcher对象结合类注解路径和方法注解路径,如果没有通配符则简单拼接如 /person , /list --> /person/list
重新创建一个返回
书接前文#2
AbstractHandlerMethodMapping中使用MappingRegistry属性对象注册
// 创建HandlerMethod对象,后文详解#2-1
// 将映射和对应的方法存起来
// 获得映射路径,将映射路径和映射对象存起来。后文详解#2-2
// 获得RequestMappingInfo的name,将name和method存起来
// 将映射对象和映射注册对象存起来
书接前文#2-1
HandlerMethod中,有beanName,beanFactory,method,methodParameter
书接前文#2-2
获得RequestMappingInfo中的PatternsRequestCondition中的patterns属性值
至此RequestMappingHandlerMapping的初始化完成了