前言: 相信大部分的Java程序猿之前所接觸到的業務都是使用同步的方式來實現交互的,但是有時候可能接觸到的業務不是同步的,需要異步實現。例如和第三方的系統進行交互的時候,我們可以採用多線程,消息隊列的方式等等,其實如果業務不是很複雜的話,我們可以採用spring boot中的@Async註解來實現異步調用的效果,在spring 3.x之後,就已經內置了@Async註解,下面就詳細講解一下如何使用@Async註解。
1. 第一步肯定是在pom.xml中引用
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.1.RELEASE</version> </parent> <dependencies> <!-- SpringBoot 核心組件 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </dependency> </dependencies>
2. 第二步是在springboot的啓動類中加上@EnableAsync,開啓異步調用
/** * 服務提供者 (eureka client) Eureka 服務提供者 @EnableEurekaClient向服務中心註冊 服務 */ @EnableEurekaClient @EnableSwagger2 @SpringBootApplication(exclude = DataSourceAutoConfiguration.class) @EnableTransactionManagement @EnableAsync //開啓異步調用 public class EurekaClientApplication { public static void main(String[] args) { SpringApplication.run(EurekaClientApplication.class, args); } @Bean public Docket createRestApi() {// 創建API基本信息 return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.ctp.eurekaclient.controller"))// 掃描該包下的所有需要在Swagger中展示的API,@ApiIgnore註解標註的除外 .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() {// 創建API的基本信息,這些信息會在Swagger UI中進行顯示 return new ApiInfoBuilder() .title("Spring Boot中使用Swagger2構建RESTful APIs")// API 標題 .description("項目提供的RESTful APIs")// API描述 .version("1.0")// 版本號 .build(); }
3. 第三步建立AsyncService服務類
@Component public class AsyncService { @Async public void method(){ System.out.println("async method run ====== "); } }
4. 第四步在controller中調用AsyncService服務類即可,整個配置完成
另外,如果異步任務處理的是比較密集,消耗性能的任務,我們可以結合多線程中的線程池來使用,如下:
1. 配置ThreadPoolTaskExecutor
@Configuration public class ThreadPoolTaskExecutorConfig { @Bean public ThreadPoolTaskExecutor initThreadPoolTaskExecutor(){ ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setThreadNamePrefix("ThreadTask-Executor"); executor.setCorePoolSize(20); executor.setMaxPoolSize(200); executor.setQueueCapacity(100); executor.setWaitForTasksToCompleteOnShutdown(true); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); executor.initialize(); return executor; } }
2. 使用ThreadPoolTaskExecutorConfig
@Component public class AsyncService { @Autowired ThreadPoolTaskExecutor threadPoolTaskExecutor; @Async public void method(){ threadPoolTaskExecutor.execute(new Runnable() { @Override public void run() { System.out.println("async method run ====== "); } }); } }