SpringMVC源码解读番外 --- WebMvcConfigurationSupport

       在前面SpringMVC源码解读部分,我们都是通过xml配置文件去处理例如HandlerMapping、HanlderAdapter、ViewResolver、HandlerMethodArgumentResolver接口。但如今我们一般是直接用注解扫描处理这些的注入,要注入关于SpringMVC的Bean,我们可以直接通过@EnableWebMvc注解来处理注入一些默认需要的接口。只需要在SpringMVC的配置文件中加上扫描的内容就可以了,例如:

<context:component-scan base-package="web" />

   我们只需要加入扫描这个标签就可以了,然后将EnableWebMvc注解的类放到这个包下面。

  例如我们创建一个类,加上注解:

@Configuration
@EnableWebMvc
public class WebEnableConfig
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}

  可以看到这里是引入了DelegatingWebMvcConfiguration。

@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {

  其继承与WebMvcConfigurationSupport,这个我们就很熟悉了。这里主要就是通过WebMvcConfigurationSupport注入这些Bean。

    1、WebMvcConfigurationSupport

public class WebMvcConfigurationSupport implements ApplicationContextAware, ServletContextAware {

    下面我们来看下其是怎样注入这些接口实现Bean的。

   1、RequestMappingHandlerMapping

@Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
   RequestMappingHandlerMapping mapping = createRequestMappingHandlerMapping();
   mapping.setOrder(0);
   mapping.setInterceptors(getInterceptors());
   mapping.setContentNegotiationManager(mvcContentNegotiationManager());
   mapping.setCorsConfigurations(getCorsConfigurations());
   ............
   return mapping;
}
protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() {
   return new RequestMappingHandlerMapping();
}

   可以看到这就是RequestMappingHandlerMapping的注入。其会获取设置Interceptor:

protected final Object[] getInterceptors() {
   if (this.interceptors == null) {
      InterceptorRegistry registry = new InterceptorRegistry();
      addInterceptors(registry);
      registry.addInterceptor(new ConversionServiceExposingInterceptor(mvcConversionService()));
      registry.addInterceptor(new ResourceUrlProviderExposingInterceptor(mvcResourceUrlProvider()));
      this.interceptors = registry.getInterceptors();
   }
   return this.interceptors.toArray();
}
protected void addInterceptors(InterceptorRegistry registry) {
}

  所以我们一般继承WebMvcConfigurationSupport,然后重写其的addInterceptors来注入我们自定义的Interceptor,然后在创建HandlerMapping的时候。,就是这样将其设置到HandlerMapping中的。

  2、BeanNameUrlHandlerMapping

@Bean
public BeanNameUrlHandlerMapping beanNameHandlerMapping() {
   BeanNameUrlHandlerMapping mapping = new BeanNameUrlHandlerMapping();
   mapping.setOrder(2);
   mapping.setInterceptors(getInterceptors());
   mapping.setCorsConfigurations(getCorsConfigurations());
   return mapping;
}

 类似的BeanNameUrlHandlerMapping也是对应的这种设置。

 下面我们来看下HandlerAdapter

3、RequestMappingHandlerAdapter

@Bean
public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
   RequestMappingHandlerAdapter adapter = createRequestMappingHandlerAdapter();
   ..........
   adapter.setMessageConverters(getMessageConverters());
   adapter.setWebBindingInitializer(getConfigurableWebBindingInitializer());
   adapter.setCustomArgumentResolvers(c());
   adapter.setCustomReturnValueHandlers(getReturnValueHandlers());
     ........
   .........
   return adapter;
}

  然后这里的几个get方法也是与前面getInterceptors类似。不过getMessageConverters方法,是注入HttpMessageConverter,这个接口的作用在前面梳理过。其会有一些默认的,也是在个getMessageConverters方法中调用的:

protected final List<HttpMessageConverter<?>> getMessageConverters() {
   if (this.messageConverters == null) {
      this.messageConverters = new ArrayList<>();
      configureMessageConverters(this.messageConverters);
      if (this.messageConverters.isEmpty()) {
         addDefaultHttpMessageConverters(this.messageConverters);
      }
      extendMessageConverters(this.messageConverters);
   }
   return this.messageConverters;
}
protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
}
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
}
protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
}
protected final void addDefaultHttpMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
    ...........
   messageConverters.add(new ResourceHttpMessageConverter());
     .........
   if (romePresent) {
      messageConverters.add(new AtomFeedHttpMessageConverter());
      messageConverters.add(new RssChannelHttpMessageConverter());
   }
   .........
   if (jackson2SmilePresent) {
      Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.smile();
      if (this.applicationContext != null) {
         builder.applicationContext(this.applicationContext);
      }
      messageConverters.add(new MappingJackson2SmileHttpMessageConverter(builder.build()));
   }
    ........
}
private static final boolean jackson2SmilePresent =
      ClassUtils.isPresent("com.fasterxml.jackson.dataformat.smile.SmileFactory",
            WebMvcConfigurationSupport.class.getClassLoader());

    这些以Present结尾的例如jackson2SmilePresent,就是根据当前加载的所有class中有没有SmileFactory接口,代表有加入这个包,这个与SpringBoot的应用包就默认注入一些类,并进行默认配置。

 4、HttpRequestHandlerAdapter等

@Bean
public HttpRequestHandlerAdapter httpRequestHandlerAdapter() {
   return new HttpRequestHandlerAdapter();
}
@Bean
public SimpleControllerHandlerAdapter simpleControllerHandlerAdapter() {
   return new SimpleControllerHandlerAdapter();
}

   这里主要是引出其的处理流程,梳理通过WebMvcConfigurationSupport注入与SpringMVC处理相关的接口。具体整个又引入那些,这里就不再一一列举了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值