摘要
- 异步调用传统SSM项目实现
- 异步调用SpringBoot实现
Async简介:
异步方法调用使用场景:处理日志、发送邮件、短信......
spring中提供了@Async来实现异步方法。
@Async修饰类,则该类所有方法都是异步的,@Async修饰方法,则该方法是异步的。
被修饰的方法在被调用时,会在一个新的线程中执行。
实现
传统SSM项目实现
- AsyncTask类
@Component
public class AsyncTask {
protected static Logger logger = LoggerFactory.getLogger(AsyncTask.class);
@Async
public void doSomeThing(String s){
logger.info("son"+Thread.currentThread());
//doSomeThing
logger.info(s);
}
}
AsyncTask类中也可以注入LogService来往数据库记日志
- xml文件配置
<!-- 激活组件扫描功能,扫描aop的相关组件组件 -->
<context:component-scan base-package="com.gs"/>
<!-- 支持异步方法执行 -->
<task:annotation-driven />
<!-- 支持异步方法执行 以下是配置执行器的方式 -->
<!--<task:annotation-driven executor="myExecutor" scheduler="defaultTaskScheduler" />-->
<!--<bean id="myExecutor" class="com.gs.teacher.task.MyExecutor">-->
<!--<constructor-arg ref="defaultTaskExecutor" />-->
<!--</bean>-->
<!--<task:executor id="defaultTaskExecutor" pool-size="5" />-->
<!--<task:scheduler id="defaultTaskScheduler" pool-size="1" />
若不配置执行器,则使用默认的执行器。
- Controller注入
@Controller
@RequestMapping("teacher")
public class TeacherController {
protected static Logger logger = LoggerFactory.getLogger(TeacherController.class);
@Autowired
private ITeacherService teacherService;
@Autowired
private AsyncTask asyncTask;
@RequestMapping(value = "/get/{id}", method = RequestMethod.GET)
@ResponseBody
public BaseResult<TeacherVO> get(@PathVariable("id")Integer id){
TeacherVO vo = teacherService.getVOById(id);
logger.info("main"+Thread.currentThread());
asyncTask.doSomeThing("do Something");
return new BaseResult<TeacherVO>(true, vo);
}
}
- 执行结果
INFO[com.gs.teacher.controller.TeacherController:36]- mainThread[http-apr-8082-exec-7,5,main]
INFO[com.gs.teacher.task.AsyncTask:15]- sonThread[defaultTaskExecutor-1,5,main]
SpringBoot实现
SpringBoot的实现方式很简单
- AsyncTask类
@Component
public class AsyncTask {
protected static Logger logger = LoggerFactory.getLogger(AsyncTask.class);
@Async
public void doSomeThing(String s){
logger.info("son"+Thread.currentThread());
//doSomeThing
logger.info(s);
}
}
- Application上加注解
@SpringBootApplication
@EnableAsync
public class Application extends SpringBootServletInitializer {
protected final static Logger logger = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
这种配置不指定Executor,会使用默认的Executor
- Controller注入
@Controller
@RequestMapping("teacher")
public class TeacherController {
protected static Logger logger = LoggerFactory.getLogger(TeacherController.class);
@Autowired
private ITeacherService teacherService;
@Autowired
private AsyncTask asyncTask;
@RequestMapping(value = "/get/{id}", method = RequestMethod.GET)
@ResponseBody
public BaseResult<TeacherVO> get(@PathVariable("id")Integer id){
TeacherVO vo = teacherService.getVOById(id);
logger.info("main"+Thread.currentThread());
asyncTask.doSomeThing("do Something");
return new BaseResult<TeacherVO>(true, vo);
}
}
- 执行结果
INFO[com.gs.teacher.controller.TeacherController:36]- mainThread[http-apr-8082-exec-7,5,main]
INFO[com.gs.teacher.task.AsyncTask:15]- sonThread[defaultTaskExecutor-1,5,main]
复制上面的执行结果。。。懒得跑了
- pringBoot配置Executor
/**
* @author gs
* @create 2017/11/21
* @desc 异步方法调用的Executor
*/
@Configuration
@EnableAsync
public class ExecutorConfig {
/** 初始线程数. */
private int corePoolSize = 10;
/** 最大线程数. */
private int maxPoolSize = 200;
/** 阻塞队列大小. */
private int queueCapacity = 10;
@Bean
public Executor mySimpleAsync() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setThreadNamePrefix("MySimpleExecutor-");
executor.initialize();
return executor;
}
}
新建配置文件ExecutorConfig将Application上的@EnableAsync移至此处
- AsyncTask文件@Async指定执行器
@Component
public class AsyncTask {
protected static Logger logger = LoggerFactory.getLogger(AsyncTask.class);
@Async("mySimpleAsync")
public void doSomeThing(String s){
logger.info("son"+Thread.currentThread());
//doSomeThing
logger.info(s);
}
}
- 执行结果
INFO[com.gs.teacher.controller.TeacherController:36]- mainThread[http-apr-8082-exec-7,5,main]
INFO[com.gs.teacher.task.AsyncTask:15]- sonThread[mySimpleAsync-1,5,main]
改了一下上面的执行结果。。。真的懒得跑了!