Springboot如何動態注冊處理請求接口?這個知識點你值得了解一下
環境:springboot2.2.10.RELEASE
編寫一個準備用來出來請求的方法
- @Service
- public class UserHandler {
- @ResponseBody
- public Object getUsers(@PathVariable("id") String id, HttpServletRequest request) {
- System.out.println(request) ;
- return "查詢用戶ID為: " + id ;
- }
- }
你的處理程序可以不是受容器管理的Bean。這里還應用了SpringMVC相關的一些注解,這些注解都可以像Controller中使用一樣。
注冊接口處理程序
- @Configuration
- public class MappingConfig {
- @Autowired
- public void setHandlerMapping(RequestMappingHandlerMapping mapping, UserHandler handler) throws NoSuchMethodException {
- RequestMappingInfo info = RequestMappingInfo.paths("/users/{id}").methods(RequestMethod.GET).build();
- Method method = UserHandler.class.getMethod("getUsers", String.class, HttpServletRequest.class);
- mapping.registerMapping(info, handler, method);
- }
- }
- 創建RequestMappingInfo對象,就是一些請求的基本元信息。
- 獲取處理程序的方法對象。
- 通過RequestMappingHandlerMapping注冊請求映射對象。
Spring容器在啟動過程中會將所有的Controller處理接口方法都包裝成RequestMappingInfo對象然后添加到
RequestMappingHandlerMapping對象的一個集合中。
注:容器默認有很多個HandlerMapping對象,具體該如何處理初始化那些類接口是通過
AbstractHandlerMethodMapping#isHandler決定,該方法是個抽象方法具體是由子類來實現的。
- public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMapping implements InitializingBean {
- protected abstract boolean isHandler(Class<?> beanType);
- }
RequestMappingHandlerMapping是AbstractHandlerMethodMapping的子類看看它的實現:
- public class RequestMappingHandlerMapping {
- @Override
- protected boolean isHandler(Class<?> beanType) {
- return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
- AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
- }
- }
這里判斷了當前Bean對象上是否有@Controller注解或者@RequestMapping對象;也就是在容器啟動后會將所有的Controller中的接口方法保證注冊為RequstMappingInfo對象。
在SpringMVC處理一個請求的過程中,有一個流程是取得相應的HandlerMapping對象。
處理方法參數
處理程序能夠接收那些參數?
JDK 8的java.util.Optional作為方法參數與注釋相結合受到支持具有必需屬性(例如@RequestParam、@RequestHeader和其他屬性)且等效于required=false。

處理方法返回值
