前言: 相信大部分的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 ====== "); } }); } }