@EnableAsync vs AbstractDispatcherServletInitializer#isAsyncSupported()

时间:2018-04-22 13:12:57

标签: spring-mvc

我对@EnableAsyncAbstractDispatcherServletInitializer#isAsyncSupported()之间的区别感到困惑。

根据link

  

AbstractDispatcherServletInitializer的isAsyncSupported受保护方法提供了一个位置,用于在DispatcherServlet上启用异步支持以及映射到它的所有过滤器。默认情况下,此标志设置为true

根据我的知识,@EnableAsync是启用扫描@Async注释并提供多线程支持。但我仍然无法理解何时使用AbstractDispatcherServletInitializer#isAsyncSupported()

2 个答案:

答案 0 :(得分:0)

如果我们想要体验Spring MVC提供的好处并且不想手动注册DispatcherServlet,那么最好使用它: AbstractDispatcherServletInitializer 。它添加了两个抽象方法:createServletApplicationContext()和getServletMappings()。 第一种方法返回将传递给DispatcherServlet的WebApplicationContext,它将自动添加到容器ServletContext中。此上下文将作为createRootApplicationContext()方法返回的上下文的子项建立。第二种方法 - 返回在servlet注册期间使用的映射。

@EnableAsync 注释会切换Spring在后台线程池中运行@Async方法的能力。通过简单地将@EnableAsync添加到配置类来启用使用Java配置的异步处理。

@EnableAsync
@Configuration
public class SpringAsyncConfigurer implements AsyncConfigurer {...}

@Async仅适用于公共方法。 在同一个类中调用@Async方法是行不通的。

答案 1 :(得分:0)

两者之间存在很大差异,@EnableAsync@Async不关心spring-web-mvc,它们允许使用TaskExecutor异步执行方法。例如,如果您有一个删除服务器中的所有日志的清理服务,您可以允许其doCleanUp方法异步运行而无需编写调度代码,spring将为您处理:

public class CleanUpService {

     @Async
     public void doCleanUp() {
         // This code will be executed using a different thread than the calling thread by a TaskExecuter
     }
}

正如您所看到的,这与Web开发尤其无关。另请注意,此方法返回void,但如果您希望它返回结果,例如CleanupStatistics,则不能只写这样的方法

 @Async
 public CleanupStatistics doCleanUp() {
     // This code will be executed using a different thread than the calling thread by a TaskExecuter
     return new CleanupStatistics("someinformation");
 }

required要返回voidFutureFuture表示异步计算的结果,可用于在计算可用时获取计算结果。我们将回到Future,看看在isAsyncSupported为真时如何在控制器方法中使用它。

isAsyncSupported是一个完全不同的故事,这个标志启用Servlet 3.0异步请求处理,在Servlet 3.0之前一个servlet容器(例如Tomcat)将有一个线程池来处理Http请求,每个线程都会处理请求直到处理完成,即使线程必须保持空闲,例如,等待数据库查询完成或API调用结果返回。这会影响servlet容器的可伸缩性。在Servlet 3.0中,请求可以异步处理,容器线程将调用您的处理程序方法,反过来,处理程序方法可以调度其工作异步完成并立即返回,在结果可用后释放容器线程以处理其他请求任何容器线程都可以恢复请求的处理。从客户端的角度来看,没有任何改变,客户端一直在等待结果返回,但从服务器的角度来看,容器线程的利用率更高。

在spring-mvc中,您可以通过返回某些java类型来触发控制器方法的异步请求处理,例如

  • DeferredResult
  • Callable
  • ListenableFuture
  • CompletionStage
  • CompletableFuture
  • 反应类型
  • 和流媒体类型

如果您想在isAsyncSupported中使用@Async,您可以编写一个控制器方法,该方法调用使用@Async注释的方法并返回ListenableFuture

您可以详细了解任务执行和日程安排here。更多关于Servlet 3.0 asynch here