Spring中DispatcherHandler的初始化过程
在Spring Boot中HttpHandler的创建过程一文中,介绍到在WebFluxConfigurationSupport类中会向bean工厂中注册DispatcherHandler类型的bean。在创建后Spring会对该bean进行初始化,以满足处理请求的需要。本文就来分析一下初始化过程中做了哪些事情。
创建过程
java
spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurationSupport.java
/*
* 注册WebFlux的核心组件:DispatcherHandler,bean的名称为webHandler
* bean的名称正如方法名:webHandler,
* 在WebHttpHandlerBuilder中会被获取,使用的是常量属性WEB_HANDLER_BEAN_NAME,该常量的值就是webHandler。
*/
@Bean
public DispatcherHandler webHandler() {
return new DispatcherHandler();
}
其实在WebFluxConfigurationSupport中,还会创建其他组件,如RouterFunctionMapping、RequestMappingHandlerAdapter等。
DispatcherHandler构造方法
java
spring-webflux/src/main/java/org/springframework/web/reactive/DispatcherHandler.java
public DispatcherHandler() {
}
public DispatcherHandler(ApplicationContext applicationContext) {
initStrategies(applicationContext);
}
该类有两个构造方法,但是上面调用的是无参构造方法,所以此时还不会执行初始化操作。
初始化过程
DispatcherHandler实现了ApplicationContextAware接口,所以被Spring创建bean后会调用setApplicationContext方法。
java
spring-webflux/src/main/java/org/springframework/web/reactive/DispatcherHandler.java
/*
* 这个方法中获取的依赖在WebFluxConfigurationSupport中有注入,
* 而@EnableWebFlux注解引入了配置类DelegatingWebFluxConfiguration,这个类就是前者的子类。
* 在SpringBoot中可以不用指定@EnableWebFlux,而在WebFluxAutoConfiguration中定义了一个DelegatingWebFluxConfiguration的子类。
*/
protected void initStrategies(ApplicationContext context) {
/*
* 从容器上下文中获取HandlerMapping实例
* 主要参考:RequestMappingHandlerMapping,注意这是reactive包下的,不是webmvc包下的,两个类同名。
*/
Map<String, HandlerMapping> mappingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(
context, HandlerMapping.class, true, false);
ArrayList<HandlerMapping> mappings = new ArrayList<>(mappingBeans.values());
AnnotationAwareOrderComparator.sort(mappings);
this.handlerMappings = Collections.unmodifiableList(mappings);
/*
* 从容器上下文中获取HandlerAdapter实例
* 主要参考:RequestMappingHandlerAdapter,注意这是reactive包下的,不是webmvc包下的,两个类同名。
*/
Map<String, HandlerAdapter> adapterBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(
context, HandlerAdapter.class, true, false);
this.handlerAdapters = new ArrayList<>(adapterBeans.values());
AnnotationAwareOrderComparator.sort(this.handlerAdapters);
/*
* 从容器中获取HandlerResultHandler实例
* 主要参考:ResponseBodyResultHandler,这个最常用。
*/
Map<String, HandlerResultHandler> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(
context, HandlerResultHandler.class, true, false);
this.resultHandlers = new ArrayList<>(beans.values());
AnnotationAwareOrderComparator.sort(this.resultHandlers);
}
该方法中主要是在获取3种类型的bean,后续处理请求时会被用到。
- HandlerMapping:默认情况下会注册下面3种类型的bean,越靠前优先级越高。
- RouterFunctionMapping;
- RequestMappingHandlerMapping;
- SimpleUrlHandlerMapping;
- HandlerAdapter:默认情况下会注册下面4种类型的bean,越靠前的优先级越高。
- WebSocketHandlerAdapter;
- RequestMappingHandlerAdapter;
- HandlerFunctionAdapter;
- SimpleHandlerAdapter;
- HandlerResultHandler:默认情况下会注册下面4种类型的bean,越靠前的优先级越高。
- ResponseEntityResultHandler;
- ServerResponseResultHandler;
- ResponseBodyResultHandler;
- ViewResolutionResultHandler;
一般来说我们大部分时候都是使用的RequestMappingHandlerMapping、RequestMappingHandlerAdapter和ResponseBodyResultHandler。
在Spring Cloud Gateway中,会使用到RoutePredicateHandlerMapping(Spring Cloud Gateway中提供的类)和SimpleHandlerAdapter。