Spring 中让一个方法在新线程中运行,只需要给方法加上 @Async
注解就可以(当然也可以自己直接创建一个线程实现异步执行)。
典型的使用如用户注册后需要发送一封邮件进行验证,邮件发送完成的时间取决于很多因素,例如网络快的时候发的快一些,慢的时候需要多一些的时间。如果使用同步的方式发送邮件,有可能需要等很久邮件才发送完成然后用户才能得到注册成功的响应,体验不是很好,如果使用异步的方式发送邮件,在发邮件的同时用户就被告知注册成功,请去收件箱中查看邮件进行注册验证(异步的方式还可以使用 MQ)。
Spring 配置文件中启用异步
1 2 3 4 5 6 7 8 9 10
| <beans xmlns="http://www.springframework.org/schema/beans" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation=" http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd"> ... <task:executor id="myExecutor" pool-size="5"/> <task:annotation-driven executor="myExecutor"/> ... </beans>
|
需要异步执行的方法加上 @Sync
注意: 如果把 @Async
的方法定义在 Controller 中则异步不会生效
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package com.xtuer.service;
import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service;
@Service public class AsyncService {
@Async public void asyncMethod() { try { for (int i = 0; i < 10; ++i) { System.out.println("==> " + i); Thread.sleep(1000); } } catch (Exception ex) {} } }
|
Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package com.xtuer.controller;
import com.xtuer.service.AsyncService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;
@Controller public class AsyncController { @Autowired private AsyncService asyncService;
@RequestMapping("/async") @ResponseBody public String async() { asyncService.asyncMethod(); return "Async"; } }
|
测试