> 文章列表 > Spring MVC(Boot) Servlet 3.0异步处理,DeferredResult和Callable(续篇)

Spring MVC(Boot) Servlet 3.0异步处理,DeferredResult和Callable(续篇)

Spring MVC(Boot) Servlet 3.0异步处理,DeferredResult和Callable(续篇)

目录

    • 背景
    • 意外发现
    • 结论

背景

  • 上篇Spring MVC(Boot) Servlet 3.0异步处理,DeferredResult和Callable,我把WebMvcConfig 代码加入项目后,会报冲突的问题。如下所示。

Spring MVC(Boot) Servlet 3.0异步处理,DeferredResult和Callable(续篇)

  • requestMappingHandlerMapping: defined by method ‘requestMappingHandlerMapping’ in class path resource [com/works/framework/config/WebMvcConfig.class]
    - controllerEndpointHandlerMapping: defined by method ‘controllerEndpointHandlerMapping’ in class path resource [org/springframework/boot/actuate/autoconfigure/endpoint/web/servlet/WebMvcEndpointManagementContextConfiguration.class]

意外发现

  • 我找到创建requestMappingHandlerMapping的地方是WebMvcAutoConfiguration。这块是Spring Boot自动装配的代码。
    Spring MVC(Boot) Servlet 3.0异步处理,DeferredResult和Callable(续篇)

  • 我想requestMappingHandlerMapping框架自动配置了,那异步可以自动配置吗?

  • 于是我搜索关键字configureAsyncSupport,还真的有自动配置异步的方法。如下图所示。
    Spring MVC(Boot) Servlet 3.0异步处理,DeferredResult和Callable(续篇)

  • 只要有Bean的名称是TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME并且是属于AsyncTaskExecutor的对象,那就能自动配置异步处理的线程池了。

  • 另外,TaskExecutionAutoConfiguration是自动配置线程池的配置类。
    Spring MVC(Boot) Servlet 3.0异步处理,DeferredResult和Callable(续篇)

  • 只要有对应的配置,就可以初始化线程池和异步,可以看出Spring Boot在约定配置这块很智能。

结论

  • 那么Spring MVC(Boot) Servlet 3.0异步处理,Callable方式就有3种方案了。

    • 继承WebMvcConfigurationSupport
    • 实现 WebMvcConfigurer 接口。
    • 创建Bean的名称是TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME并且是属于AsyncTaskExecutor的对象。
  • 我直接在我创建线程池的地方增加了一个BeanName。代码如下

	...省略...@Bean(name = {"threadPoolTaskExecutor",TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME})public ThreadPoolTaskExecutor threadPoolTaskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setMaxPoolSize(maxPoolSize);executor.setCorePoolSize(corePoolSize);executor.setQueueCapacity(queueCapacity);executor.setKeepAliveSeconds(keepAliveSeconds);// 线程池对拒绝任务(无线程可用)的处理策略 ,CallerRunsPolicy 如果没有线程了,用主线程executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());executor.setThreadNamePrefix("taskExecutor-");return executor;}...省略...