doc: 阅读webflux controller文档

This commit is contained in:
asahi
2025-03-11 19:15:02 +08:00
parent 64d8c576ab
commit d04f72efc0

View File

@@ -320,3 +320,127 @@ webflux应用中包含的spring configuration通常包括
- 被委托给`webHandler`的beans - 被委托给`webHandler`的beans
- 其他 - 其他
上述配置将被被`WebHttpHandlerBuilder`使用用于构建process chain示例如下所示
```java
ApplicationContext context = ...
HttpHandler handler = WebHttpHandlerBuilder.applicationContext(context).build();
```
上述示例中返回的handler可以和`server adapter`结合使用。
### DispatcherHandler委托
`DispatcherHandler`会将请求的委托给特定的bean对象bean对象会处理请求并且将结果渲染到response中。
DispatcherHandler会对如下类型的bean进行auto-detect。
<table id="webflux-special-beans-table" class="tableblock frame-all grid-all stripes-odd stretch">
<colgroup>
<col style="width: 33.3333%;">
<col style="width: 66.6667%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Bean type</th>
<th class="tableblock halign-left valign-top">Explanation</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>HandlerMapping</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Map a request to a handler. The mapping is based on some criteria, the details of
which vary by <code>HandlerMapping</code> implementationannotated controllers, simple
URL pattern mappings, and others.</p>
<p class="tableblock"> The main <code>HandlerMapping</code> implementations are <code>RequestMappingHandlerMapping</code> for
<code>@RequestMapping</code> annotated methods, <code>RouterFunctionMapping</code> for functional endpoint
routes, and <code>SimpleUrlHandlerMapping</code> for explicit registrations of URI path patterns
and <code>WebHandler</code> instances.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>HandlerAdapter</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Help the <code>DispatcherHandler</code> to invoke a handler mapped to a request regardless of
how the handler is actually invoked. For example, invoking an annotated controller
requires resolving annotations. The main purpose of a <code>HandlerAdapter</code> is to shield the
<code>DispatcherHandler</code> from such details.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>HandlerResultHandler</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Process the result from the handler invocation and finalize the response.
See <a href="#webflux-resulthandling">Result Handling</a>.</p></td>
</tr>
</tbody>
</table>
### Processing
`DispatcherHandler`按照如下方式处理请求:
- 首先,会挨个查询`HandlerMapping`用于查找匹配的handler会匹配第一个匹配的handler
- 如果匹配到handler会通过对应的HandlerAdapter执行该handler并且会将handler返回的值作为`HandlerResult`暴露
- `HandlerResult`将会被分配给指定的`HandlerResultHandler`进行处理可能会直接向response中写入数据或渲染view
### Result Handling
通过`HandlerAdapter`对handler进行调用返回的结果会被包裹在`HandlerResult`中,随之还包含额外的上下文。
`HandlerResult`将会被传递给第一个支持其的上下文,下表中展示了`HandlerResultHandler`的实现:
<table class="tableblock frame-all grid-all stripes-odd stretch">
<colgroup>
<col style="width: 25%;">
<col style="width: 50%;">
<col style="width: 25%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Result Handler Type</th>
<th class="tableblock halign-left valign-top">Return Values</th>
<th class="tableblock halign-left valign-top">Default Order</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>ResponseEntityResultHandler</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>ResponseEntity</code>, typically from <code>@Controller</code> instances.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>ServerResponseResultHandler</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>ServerResponse</code>, typically from functional endpoints.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">0</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>ResponseBodyResultHandler</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Handle return values from <code>@ResponseBody</code> methods or <code>@RestController</code> classes.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">100</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>ViewResolutionResultHandler</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>CharSequence</code>, <a href="https://docs.spring.io/spring-framework/docs/6.2.3/javadoc-api/org/springframework/web/reactive/result/view/View.html"><code>View</code></a>,
<a href="https://docs.spring.io/spring-framework/docs/6.2.3/javadoc-api/org/springframework/ui/Model.html">Model</a>, <code>Map</code>,
<a href="https://docs.spring.io/spring-framework/docs/6.2.3/javadoc-api/org/springframework/web/reactive/result/view/Rendering.html">Rendering</a>,
or any other <code>Object</code> is treated as a model attribute.</p>
<p class="tableblock"> See also <a href="#webflux-viewresolution">View Resolution</a>.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>Integer.MAX_VALUE</code></p></td>
</tr>
</tbody>
</table>
## Annotated Controllers
spring webflux提供了基于注解的编程模型通过使用注解来向外暴露request mappings。通过注解标注的controllers可包含灵活的方法签名并且无需继承任何基类或实现指定接口。
使用示例如下所示:
```java
@RestController
public class HelloController {
@GetMapping("/hello")
public String handle() {
return "Hello WebFlux";
}
}
```
### @Controller
在基于注解的webflux变成模型中可以使用`@Controller``@RestController`来声明controller bean。
#### AOP
对于部分场景需要在运行时使用aop proxy来对controller进行decorate。
对于针对controller的aop推荐使用`class-based proxy`,可以使用`@EnableTransactionManagement(proxyTargetClass=true)`来实现。