HandlerAdapter之RequestMappingHandlerAdapter初始化

一、类图

1.1 HandlerAdapter类图

image.png

 

1.2 RequestMappingHandlerAdapter类图

image.png

 

二、初始化

2.1 初始化流程

(1) 获取@ControllerAdvice注解的类封装为ControllerAdviceBean,遍历ControllerAdviceBean

提取没有@RequestMapping注解标注的,但有@ModelAttribute注解标注的方法

提取@InitBinder注解标注的方法

提取实现了RequestBodyAdvice或ResponseBodyAdvice接口

(2) 没有设置argumentResolvers则获取默认的HandlerMethodArgumentResolver

(3) 没有设置initBinderArgumentResolvers则获取默认的处理参数绑定的HandlerMethodArgumentResolver

(4) 没有设置returnValueHandlers则获取默认的HandlerMethodReturnValueHandler

 

2.2 RequestMappingHandlerAdapter

2.2.1 afterPropertiesSet

public void afterPropertiesSet() {

 // 首先执行此操作,可能会添加ResponseBody advice beans

 initControllerAdviceCache();

 

 if (this.argumentResolvers == null) {

  List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers();

  this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);

 }

 if (this.initBinderArgumentResolvers == null) {

  List<HandlerMethodArgumentResolver> resolvers = getDefaultInitBinderArgumentResolvers();

  this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);

 }

 if (this.returnValueHandlers == null) {

  List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers();

  this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);

 }

}

 

2.2.2 解析@ControllerAdvice注解标注的类 initControllerAdviceCache

// 将@ControllerAdvice注解标注的类中的@ModelAttribute注解(没有@RequestMapping注解)、@InitBinder注解标注的方法分别提取出来,若类实现了RequestBodyAdvice或ResponseBodyAdvice接口提取出来

private void initControllerAdviceCache() {

 if (getApplicationContext() == null) {

  return;

 }

 

 // 创建ControllerAdviceBean封装@ControllerAdvice注解的类

 List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());

 AnnotationAwareOrderComparator.sort(adviceBeans);

 

 List<Object> requestResponseBodyAdviceBeans = new ArrayList<>();

 

 for (ControllerAdviceBean adviceBean : adviceBeans) {

  Class<?> beanType = adviceBean.getBeanType();

  if (beanType == null) {

   throw new IllegalStateException("Unresolvable type for ControllerAdviceBean: " + adviceBean);

  }

 

  // 获取没有@RequestMapping注解标注的,但有@ModelAttribute注解标注的方法

  Set<Method> attrMethods = MethodIntrospector.selectMethods(beanType, MODEL_ATTRIBUTE_METHODS);

  if (!attrMethods.isEmpty()) {

   this.modelAttributeAdviceCache.put(adviceBean, attrMethods);

  }

 

  // @InitBinder注解标注的方法

  Set<Method> binderMethods = MethodIntrospector.selectMethods(beanType, INIT_BINDER_METHODS);

  if (!binderMethods.isEmpty()) {

   this.initBinderAdviceCache.put(adviceBean, binderMethods);

  }

 

  // beanType实现了RequestBodyAdvice或ResponseBodyAdvice接口

  if (RequestBodyAdvice.class.isAssignableFrom(beanType) || ResponseBodyAdvice.class.isAssignableFrom(beanType)) {

   requestResponseBodyAdviceBeans.add(adviceBean);

  }

 }

 

 if (!requestResponseBodyAdviceBeans.isEmpty()) {

  this.requestResponseBodyAdvice.addAll(0, requestResponseBodyAdviceBeans);

 }

 

 if (logger.isDebugEnabled()) {

  int modelSize = this.modelAttributeAdviceCache.size();

  int binderSize = this.initBinderAdviceCache.size();

  int reqCount = getBodyAdviceCount(RequestBodyAdvice.class);

  int resCount = getBodyAdviceCount(ResponseBodyAdvice.class);

  if (modelSize == 0 && binderSize == 0 && reqCount == 0 && resCount == 0) {

   logger.debug("ControllerAdvice beans: none");

  }

  else {

   logger.debug("ControllerAdvice beans: " + modelSize + " @ModelAttribute, " + binderSize +

     " @InitBinder, " + reqCount + " RequestBodyAdvice, " + resCount + " ResponseBodyAdvice");

  }

 }

}

 

getDefaultArgumentResolvers

// 返回要使用的argument resolvers,包括内置解析器和通过{@link #setCustomArgumentResolvers}提供的自定义解析器。

private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() {

 List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>();

 

 // Annotation-based argument resolution

 resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));

 resolvers.add(new RequestParamMapMethodArgumentResolver());

 resolvers.add(new PathVariableMethodArgumentResolver());

 resolvers.add(new PathVariableMapMethodArgumentResolver());

 resolvers.add(new MatrixVariableMethodArgumentResolver());

 resolvers.add(new MatrixVariableMapMethodArgumentResolver());

 resolvers.add(new ServletModelAttributeMethodProcessor(false));

 resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));

 resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters(), this.requestResponseBodyAdvice));

 resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory()));

 resolvers.add(new RequestHeaderMapMethodArgumentResolver());

 resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory()));

 resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));

 resolvers.add(new SessionAttributeMethodArgumentResolver());

 resolvers.add(new RequestAttributeMethodArgumentResolver());

 

 // Type-based argument resolution

 resolvers.add(new ServletRequestMethodArgumentResolver());

 resolvers.add(new ServletResponseMethodArgumentResolver());

 resolvers.add(new HttpEntityMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));

 resolvers.add(new RedirectAttributesMethodArgumentResolver());

 resolvers.add(new ModelMethodProcessor());

 resolvers.add(new MapMethodProcessor());

 resolvers.add(new ErrorsMethodArgumentResolver());

 resolvers.add(new SessionStatusMethodArgumentResolver());

 resolvers.add(new UriComponentsBuilderMethodArgumentResolver());

 

 // Custom arguments

 if (getCustomArgumentResolvers() != null) {

  resolvers.addAll(getCustomArgumentResolvers());

 }

 

 // Catch-all

 resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));

 resolvers.add(new ServletModelAttributeMethodProcessor(true));

 

 return resolvers;

}

 

getDefaultInitBinderArgumentResolvers

// 返回要使用的argument resolvers to use for {@code @InitBinder},以用于{@code @InitBinder} 方法,包括内置和自定义解析器

private List<HandlerMethodArgumentResolver> getDefaultInitBinderArgumentResolvers() {

 List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>();

 

 // Annotation-based argument resolution

 resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));

 resolvers.add(new RequestParamMapMethodArgumentResolver());

 resolvers.add(new PathVariableMethodArgumentResolver());

 resolvers.add(new PathVariableMapMethodArgumentResolver());

 resolvers.add(new MatrixVariableMethodArgumentResolver());

 resolvers.add(new MatrixVariableMapMethodArgumentResolver());

 resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));

 resolvers.add(new SessionAttributeMethodArgumentResolver());

 resolvers.add(new RequestAttributeMethodArgumentResolver());

 

 // Type-based argument resolution

 resolvers.add(new ServletRequestMethodArgumentResolver());

 resolvers.add(new ServletResponseMethodArgumentResolver());

 

 // Custom arguments

 if (getCustomArgumentResolvers() != null) {

  resolvers.addAll(getCustomArgumentResolvers());

 }

 

 // Catch-all

 resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));

 

 return resolvers;

}

 

getDefaultReturnValueHandlers

 

// 返回要使用的return value handlers,包括通过{@link #setReturnValueHandlers}提供的内置和自定义处理程序。

private List<HandlerMethodReturnValueHandler> getDefaultReturnValueHandlers() {

 List<HandlerMethodReturnValueHandler> handlers = new ArrayList<>();

 

 // Single-purpose return value types

 handlers.add(new ModelAndViewMethodReturnValueHandler());

 handlers.add(new ModelMethodProcessor());

 handlers.add(new ViewMethodReturnValueHandler());

 handlers.add(new ResponseBodyEmitterReturnValueHandler(getMessageConverters(),

   this.reactiveAdapterRegistry, this.taskExecutor, this.contentNegotiationManager));

 handlers.add(new StreamingResponseBodyReturnValueHandler());

 handlers.add(new HttpEntityMethodProcessor(getMessageConverters(),

   this.contentNegotiationManager, this.requestResponseBodyAdvice));

 handlers.add(new HttpHeadersReturnValueHandler());

 handlers.add(new CallableMethodReturnValueHandler());

 handlers.add(new DeferredResultMethodReturnValueHandler());

 handlers.add(new AsyncTaskMethodReturnValueHandler(this.beanFactory));

 

 // Annotation-based return value types

 handlers.add(new ModelAttributeMethodProcessor(false));

 handlers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(),

   this.contentNegotiationManager, this.requestResponseBodyAdvice));

 

 // Multi-purpose return value types

 handlers.add(new ViewNameMethodReturnValueHandler());

 handlers.add(new MapMethodProcessor());

 

 // Custom return value types

 if (getCustomReturnValueHandlers() != null) {

  handlers.addAll(getCustomReturnValueHandlers());

 }

 

 // Catch-all

 if (!CollectionUtils.isEmpty(getModelAndViewResolvers())) {

  handlers.add(new ModelAndViewResolverMethodReturnValueHandler(getModelAndViewResolvers()));

 }

 else {

  handlers.add(new ModelAttributeMethodProcessor(true));

 }

 

 return handlers;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值