Spring中实现异步调用的方式有哪些?

网站建设4年前发布
19 0 0

一位3年工作经验的小伙伴被问到这样一道面试题,说Spring中实现异步调用的方式有哪些?,今天,我给大家分享一下我的理解。,在Spring中,实现异步调用主要有三种方式,分别是注解方式、内置线程池方式和自定义线程池方式。,20230306011925a45aaca67faae5144ec0262e29144e2939e903287,可以在配置类和方法上加特定注解。首先,在配置类加上@EnableAsync来启用异步注解,,20230306011841880eca991f526190b77021afbe279030de0203350,如代码所示:,然后,使用@Async注解标记需要异步执行的方法,,20230306011842c99005287e2bf9f6627601237a225daad60402445,如代码所示:,使用@Async标记的异步方法可以带参数,也可以带有返回值。返回值类型必须是java.util.concurrent.Future或其子类,可以是以下3种类型:,20230306011842a56ba8555579320615b091dea3d68074c4219c114,1)由Java原生API提供的Future。,2)由Spring提供的ListenableFuture后者AsyncResult。,3)Java 8提供的CompletableFuture。,需要说明的是,@Async默认会使用SimpleAsyncTaskExecutor来执行,而这个线程池不会复用线程。所以,通常要使用异步处理,我们都会自定义线程池。,可以使用Spring内置的线程池来实现异步调用,比如ThreadPoolTaskExecutor 和SimpleAsyncTaskExecutor。Spring提供了许多TaskExecutor的内置实现。下面简单介绍5种内置的线程池。,2023030601184272eadcf89f92582dfc928052a2bdefd5d5c95e861,1)SimpleAsyncTaskExecutor:它不会复用线程,每次调用都是启动一个新线程。,2)ConcurrentTaskExecutor:它是Java API中Executor实例的适配器。,3)ThreadPoolTaskExecutor:这个线程池是最常用的。它公开了用于配置的bean属性,并将它包装在TaskExecutor中。,4)WorkManagerTaskExecutor:它基于CommonJ WorkManager来实现的,并且是在Spring上下文中的WebLogic或WebSphere中设置CommonJ线程池的工具类。,5)DefaultManagedTaskExecutor:主要用于支持JSR-236兼容的运行时环境,它是使用JNDI获得ManagedExecutorService,作为CommonJ WorkManager的替代方案。,通常情况下,ThreadPoolTaskExecuto最为常用,只要当ThreadPoolTaskExecutor不能满足需求时,可以使用ConcurrentTaskExecutor。如果在代码中声明了多个线程池,Spring会默认按照以下搜索顺序来调用线程池:,20230306011926394f51b23993d6e7b8c305e2c09deeb840475d594,第一步,检查上下文中的唯一TaskExecutor Bean。,第二步,检查名为“ taskExecutor”的Executor Bean。,第三步,以上都无法无法处理,就会使用SimpleAsyncTaskExecutor来执行。,可以通过实现AsyncConfigurer接口或者直接继承AsyncConfigurerSupport类来自定义线程池。但是非完全托管的Bean和完全托管的Bean实现方式有点小差异。,20230306011842335873644f8b37dcac71988926bad0ef7875f2315,首先,来看非完全托管的Spring Bean,实现方式如代码所示:,2023030601194612a1c9941992ed38717247f3a77b9d555d7202274,在这段代码中,ThreadPoolTaskExecutor不是完全托管的Spring bean。,然后,来看完全托管的Spring Bean,实现方式如代码所示:,2023030601184408e0b9c8879f6fbe338634389ed2cbc2e0d985942,只要在异步方法上添加@Bean注解,不需要手动调用线程池的initialize()方法,在Bean在初始化之后会自动调用。需要注意的是,在同级类中直接调用异步方法无法实现异步。,以上就是我对Spring实现异步调用的理解。

© 版权声明

相关文章