springboot使用@Async實現異步調用的作用

前言:  相信大部分的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 ====== ");
            }
        });
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章