Spring Boot @Async 简单实践

背景

需要把一些调用其它服务器的执行时间比较长的方法异步化,这样就不要等待这些方法执行完后才执行其它的方法的。可以转换为异步方法的条件是

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";
    }
    
}

猜你喜欢

转载自blog.csdn.net/keeppractice/article/details/124253040