Spring 通过任务执行器 TaskExecutor 来实现多线程和并发编程, 使用 ThreaPoolTaskExector 可实现一个基于线程池的 TaskExecutor. 而实际开发任务一般非阻碍的,即异步.所以我们要在配置类中通过 @EnableAsync 开启对异步任务的支持.并通过在实际执行的 bean 的方法中使用 @Async 注解来声明是一个异步任务.
配置类:
package com.pangu.taskexecutor;
import java.util.concurrent.Executor;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
/**
* @ClassName: TaskExecutorConfig
* @Description: TODO 配置类
* @author etfox
* @date 2018年9月11日 下午8:52:29
*
* @Copyright: 2018 www.etfox.com Inc. All rights reserved.
*/
@Configuration
@ComponentScan("com.pangu.taskexecutor")
@EnableAsync //注解开启异步任务支持
//配置类实现 AsyncConfigurer 接口并重写 getAsyncExecutor 方法,并返回一个 ThreadPoolTaskExecutor
public class TaskExecutorConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(5);
taskExecutor.setMaxPoolSize(10);
taskExecutor.setQueueCapacity(25);
taskExecutor.initialize();
return taskExecutor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
}
}
业务类:
package com.pangu.taskexecutor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
/**
* @ClassName: AsyncTaskService
* @Description: TODO 任务执行类
* @author etfox
* @date 2018年9月11日 下午9:04:18
*
* @Copyright: 2018 www.etfox.com Inc. All rights reserved.
*/
@Service
public class AsyncTaskService {
@Async //注解表名方法是异步方法,如果在类上,则表明整个类的方法都是异步方法
public void executeAsyncTask(Integer i){
System.out.println("执行异步任务"+i);
}
@Async
public void executeAsyncTaskPlus(Integer i){
System.out.println("执行异步任务+1:"+(i+1));
}
}
测试类:
package com.pangu.taskexecutor;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class TestMain {
@Test
public void test(){
AnnotationConfigApplicationContext application =
new AnnotationConfigApplicationContext(TaskExecutorConfig.class);
AsyncTaskService ayAsyncTaskExecutor = application.getBean(AsyncTaskService.class);
for (int i = 0; i < 10; i++) {
ayAsyncTaskExecutor.executeAsyncTask(i);
ayAsyncTaskExecutor.executeAsyncTaskPlus(i);
}
application.close();
}
}
执行结果:
九月 11, 2018 11:09:34 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@7637f22: startup date [Tue Sep 11 23:09:34 CST 2018]; root of context hierarchy
九月 11, 2018 11:09:34 下午 org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker postProcessAfterInitialization
信息: Bean 'taskExecutorConfig' of type [com.pangu.taskexecutor.TaskExecutorConfig$$EnhancerBySpringCGLIB$$477743c1] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
九月 11, 2018 11:09:34 下午 org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor initialize
信息: Initializing ExecutorService
执行异步任务+1:1
执行异步任务2
执行异步任务+1:3
执行异步任务1
执行异步任务0
执行异步任务+1:2
执行异步任务+1:5
执行异步任务4
执行异步任务+1:4
执行异步任务+1:7
执行异步任务3
执行异步任务7
执行异步任务6
执行异步任务+1:6
执行异步任务5
执行异步任务9
执行异步任务+1:9
执行异步任务8
执行异步任务+1:8
执行异步任务+1:10
九月 11, 2018 11:09:34 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@7637f22: startup date [Tue Sep 11 23:09:34 CST 2018]; root of context hierarchy