1.webflux是如何执行我们的controller中的方法的。
a.写一个TestController进行debug
b.发现是InvocableHandlerMethod类调用了我们的controller
InvocableHandlerMethod.invoke方法返回了一个Mono对象中有一个值,args就是我们要执行的参数。
Mono.flatMap方法就是将其中的lamda表达式,转换成MonoFlatMap对象,而args就是Mono中的一个参数。
问题1.我们可以看一下resolveArguments是如何创建Mono对象的。
问题2.在doInvoke方法中bridgedMethod这个成员变量是怎么赋值的。
第一个问题:我们可以看一下resolveArguments是如何创建Mono对象的。
将要执行的controller.方法的参数取出来封装成Mono
第二个问题:在doInvoke方法中bridgedMethod这个成员变量是怎么赋值的。
在ControllerMethodResolver.getRequestMappingMethod中new了InvocableHandlerMethod将handlerMehtod传入,并将handlerMehtod中的bridgedMethod赋值给了InvocableHandlerMethod的bridgedMethod
继续看handlerMehtod怎么来的。
继续看这个handler怎么来的。
继续看这个handler怎么来的。
还是在一个响应流中调用的。
Flux.fromIterable(this.handlerMappings).concatMap((mapping) -> {
return mapping.getHandler(exchange);
}).next().switchIfEmpty(Mono.error(HANDLER_NOT_FOUND_EXCEPTION)).flatMap((handler) -> {
return this.invokeHandler(exchange, handler);
})
这一段代码:
1.Flux.fromIterable(this.handlerMappings)是先将handlerMappings放入Flux流中,
2. mapping.getHandler(exchange);轮询执行handlerMappings的getHandler方法
3.next()转换成Mono链
4.switchIfEmpty(Mono.error(HANDLER_NOT_FOUND_EXCEPTION))如果有一个getHandler为空就抛出HANDLER_NOT_FOUND_EXCEPTION 异常
5.this.invokeHandler(exchange, handler);handlerMappings是一个list,前面三步会根据handlerMappings生成一个放了handlerMappings长度存放了handler的调用链,最后在反应式响应流中调用DispatcherHandler.invokeHandler 将handler放入其中。
接下来我们debug这段代码发现:
这个handlerMappings有三个值。、
1.RouterFunctionMapping
2.RequestMappingHandlerMapping
3.SimpleUrlHandlerMapping
我们找到这三个类的getHandler分别打上debug
他们三个都是继承AbstractHandlerMapping,调用getHandler会先执行getHandlerInternal,getHandlerInternal由子类实现。
这里我们只关注RequestMappingHandlerMapping的getHandlerInternal
RequestMappingHandlerMapping的getHandlerInternal方法由它的父类AbstractHandlerMethodMapping实现
返回一个handlerMethod的mono对象,handlerMethod由lookupHandlerMethod创建handlerMethod
这一段代码是在addMatchingMappings的时候根据exchange匹配出一个matches,mathes中保存了一个bestMatch,bestMatch.handlerMethod就是我们的handlerMethod。
继续看addMatchingMappings是如何匹配的。
this.mappingRegistry.getMappings()中保存了uri和controller方法的映射。是一个map,key是mappingInfo,值是handlerMethod.
循环this.mappingRegistry.getMappings(),先看exhcange跟mapping能不能匹配,如果能匹配就取出mapping对应的值,然后构建成absractHandlerMethodMapping返回。
最后我们看这个this.mappingRegistry.getMappings()是如何来的。
将传入的method构建成handlerMeth,然后放入mappingLoopup中
调用:AbstractHandlerMethodMapping.MappingRegistry.register
将contoller中的方法封装成一个Map<method,mappingInfo>最后调用AbstractHandlerMethodMapping.registerHandlerMethod方法,在registerHandlerMethod方法中将controller所有的方法都封装成handler
调用ApplicationObjectSupport.obtainApplicationContext方法获取application,获取所有beanNames,再根据benName获取bean,调用RequestMappingHandlerMapping.isHandler判断bean有没有Controller注解和RequestMapping注解,有就认为它是一个handler
调用AbstractHandlerMethodMapping.detectHandlerMethods将handler存入mappingLoopup中
获取applicationContext
判断是不是controller