背景
需要把一些调用其它服务器的执行时间比较长的方法异步化,这样就不要等待这些方法执行完后才执行其它的方法的。可以转换为异步方法的条件是
1. 它没有返回值,或者有返回值但是返回值和接下来要执行的代码没有关系。
2. 它的错误和调用它的方法没有关系,或者说它的错误它自己可以处理。
1. Maven 中依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.2</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
1. 开启异步线程
在SpringBoot的启动类上面加上@EnableAsync
@SpringBootApplication
@Import(value = SpringAsyncConfig.class)
public class SpringBootClient {
public static void main(String[] args) {
SpringApplication.run( SpringBootClient.class, args );
}
}
2. 实例化自己的线程池
虽然SpringBoot已经帮我们做了默认配置,但是为了要掌握具体的内容还是可以自定义配置
@Configuration
@EnableAsync
public class SpringAsyncConfig implements AsyncConfigurer {
@Bean(name = "threadPoolTaskExecutor")
public Executor threadPoolTaskExecutor() {
return new ThreadPoolTaskExecutor();
}
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new CustomAsyncExceptionHandler();
}
}
3. 还有自定义错误处理类
public class CustomAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
System.out.println("Exception message - " + throwable.getMessage());
System.out.println("Method name - " + method.getName());
for (Object param : obj) {
System.out.println("Parameter value - " + param);
}
}
}
4. 异步方法的使用
asyncMethodWithVoidReturnType方法:不返回值
asyncMethodWithReturnType方法:有返回值
@Component
public class AsyncAnnotationExample {
@Async
public void asyncMethodWithVoidReturnType() {
System.out.println("Execute method asynchronously. "
+ Thread.currentThread().getName());
System.out.println(1/0);
}
@Async
public Future<String> asyncMethodWithReturnType() {
System.out.println("Execute method asynchronously - "
+ Thread.currentThread().getName());
try {
Thread.sleep(5000);
return new AsyncResult<String>("hello world !!!!");
} catch (InterruptedException e) {
//
}
return null;
}
}
5. 写个Controller类做测试
test1接口测试有返回的异步方法
test2接口测试无返回的异步方法。
@RestController
public class AsyncController {
@Autowired
private AsyncAnnotationExample asyncAnnotationExample;
@RequestMapping("/test1")
public String test1() {
try {
System.out.println("Invoking an asynchronous method. " + Thread.currentThread().getName());
Future<String> future = asyncAnnotationExample.asyncMethodWithReturnType();
while (true) {
if (future.isDone()) {
System.out.println("Result from asynchronous process - " + future.get());
break;
}
System.out.println("Continue doing something else. ");
Thread.sleep(1000);
}
}catch(Exception e) {
e.printStackTrace();
}
return "test1";
}
@RequestMapping("/test2")
public String test2() {
System.out.println("Invoking an asynchronous method. " + Thread.currentThread().getName());
asyncAnnotationExample.asyncMethodWithVoidReturnType();
return "test2";
}
}