美文网首页
Spring中使用@Async异步调用方法

Spring中使用@Async异步调用方法

作者: 程序员的幻想乡 | 来源:发表于2017-11-28 10:58 被阅读0次

摘要

  • 异步调用传统SSM项目实现
  • 异步调用SpringBoot实现

Async简介:

异步方法调用使用场景:处理日志、发送邮件、短信......
spring中提供了@Async来实现异步方法。
@Async修饰类,则该类所有方法都是异步的,@Async修饰方法,则该方法是异步的。
被修饰的方法在被调用时,会在一个新的线程中执行。


实现

传统SSM项目实现

  1. 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来往数据库记日志

  1. 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" />

若不配置执行器,则使用默认的执行器。

  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);
    }
}
  1. 执行结果
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的实现方式很简单

  1. 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);
    }
}
  1. 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

  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);
    }
}
  1. 执行结果
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]

复制上面的执行结果。。。懒得跑了

  1. 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移至此处

  1. 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);
    }
}
  1. 执行结果
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]

改了一下上面的执行结果。。。真的懒得跑了!

相关文章

网友评论

      本文标题:Spring中使用@Async异步调用方法

      本文链接:https://www.haomeiwen.com/subject/bnesbxtx.html