轻量级前端框架助力开发者提升项目效率与性能
1871
2022-09-14
springboot web - 建立路由(springboot框架工作原理及流程)
一. 测试代码
在 BookController 中, 有三个方法可以访问.
/book/add -> add()
/book/getById -> getById()
/book/getAll -> getAll()
url 和 对应的名字, 是可以不一样的, 比如 我新写个方法:
@GetMapping("byWhat")
public JsonResponse
}
此时的对应关系就是: /book/byWhat -> getBy() 方法.
这种映射, 就是一种路由关系. 通过地址路由到方法上.
二. 建立路由
1. 配置文件配置
DispatcherServlet.properties 文件中配置了两个路由处理类:
org.springframework.web.servlet.HandlerMapping=org.`.web.servlet.handler.BeanNameUrlHandlerMapping,\
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
2. 配置类配置
spring-boot-autoconfigure 中, 有一块专门对 web 进行配置的类, WebMvcAutoConfiguration 是其中之一
3. 类图
4. SimpleUrlHandlerMapping
由于 其 祖先类 ApplicationObjectSupport 实现了 ApplicationContextAware 接口, 所以在实例化后, 会调用 setApplicationContext() 方法:
SimpleUrlHandlerMapping 重写了 initApplicationContext 方法:
在 faviconHandlerMapping() 中, 设置了 urlMap, 经过上面的方法后, 其关系为
/**/favicon.ico -> ResourceHttpRequestHandler
然后对其进行注册:
5. BeanNameUrlHandlerMapping
这个类并没有重写 initApplicationContext() 方法. 但是他的父类 AbstractDetectingUrlHandlerMapping 重写了此方法:
接着看一下 BeanNameUrlHandlerMapping 里的方法:
determineUrlsForHandler 实现了父类留的坑, 此处主要是检测 beanName 或其别名 是否是以 "/" 开头的, 如果是, 则对其执行注册方法 registerHandler(与前面4里是同一个方法).
在此例中, 并没有 beanName 是以 "/" 开头的, 所以这里并没有进行任何注册操作.
6. RequestMappingHandlerMapping
RequestMappingHandlerMapping 并不是通过 initApplicationContext() 来进行扫描触发的.
其祖先类 AbstractHandlerMethodMapping 实现了 InitializingBean 接口, 也就是说, 在属性设置后, 会调用其 afterPropertiesSet() 方法.
但是 RequestMappingHandlerMapping 重写了 afterPropertiesSet() 方法:
super.afterPropertiesSet() 调用的就是 AbstractHandlerMethodMapping 的方法了.
isHandler() 是一个过滤方法, 判断 bean 是否有 Controller 或 RequestMapping 注解:
@Override
protected boolean isHandler(Class> beanType) {
return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
}
detectHandlerMethods() 能进来的, 此例中就 bookController 了.
methods 就是 BookController 里面的那三个方法: add , getById, getAll
查找的基本思路:
1. 拿到spring容器中所有的 beanNames
2. 遍历beanNames, 进行过滤, 过滤依据: bean上是否有 Controller 或 RequestMapping 注解修饰
3. 对 bean 进行处理, 拿到他和他所有父类中的方法
4. 对这些方法进行过滤, 过滤依据为: 方法上是否有 RequestMapping 注解修饰, 并创建 RequestMappingInfo 对象 - A.
5. 为 bean 也创建 RequestMappingInfo 对象 - B.
如果 B 为空(bean上没有 RequestMappingInfo注解修饰), 则跳过合并操作
如果B不为空, 则对 A 和 B 进行合并操作. 路径 "/book/add"也就组合出来了.
这里的 mappingLookup 存放的是 RequestMappingInfo -> HandlerMethod
而 urlLookup 存放的是 url -> RequestMappingInfo
private final Map
private final MultiValueMap
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~