一般在一個(gè)方法中需要處理多個(gè)任務(wù),其中某些任務(wù)無關(guān)緊要(如發(fā)送短信压状、記錄操作日志等)蚊荣,可以使用異步處理那些無關(guān)緊要的任務(wù),從而提高整個(gè)請(qǐng)求的相應(yīng)時(shí)間榔至。下面演示使用 Spring Boot 快速開發(fā)方法異步處理
pom.xml
依賴配置如下
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
Controller
層代碼
-
UserController
代碼如下
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/users/{id}")
public UserDTO get(@PathVariable("id") Long id) {
return userService.getById(id);
}
}
Service
層代碼
-
UserService
接口定義如下
// 接口定義
public interface UserService {
UserDTO getById(Long id);
}
-
UserServiceImpl
實(shí)現(xiàn)UserService
接口,代碼如下
// 接口實(shí)現(xiàn)
@Slf4j
@Service
public class UserServiceImpl implements UserService {
@Autowired
private LogService logService;
@Override
public UserDTO getById(Long id) {
log.info("查詢用戶");
UserDTO userDTO = new UserDTO();
userDTO.setId(id);
log.info("記錄操作日志");
logService.save();
return userDTO;
}
}
-
LogService
接口定義如下
// 接口定義
public interface LogService {
void save();
}
-
LogServiceImpl
實(shí)現(xiàn)LogService
接口欺劳,代碼如下
// 接口實(shí)現(xiàn)
@Slf4j
@Service
public class LogServiceImpl implements LogService {
@Async("logServiceExecutor") // @Async 表示該方法異步執(zhí)行唧取,"logServiceExecutor"用來指定線程池實(shí)例
@Override
public void save() {
log.info("{},{},記錄日志, start", Integer.toHexString(Thread.currentThread().hashCode()), Thread.currentThread().getName());
try {
// 休眠3秒铅鲤,異步效果更明顯
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
log.info("{},{},記錄日志, end.", Integer.toHexString(Thread.currentThread().hashCode()), Thread.currentThread().getName());
}
}
配置層
- 線程池配置代碼如下
@Slf4j
@EnableAsync
@Configuration
public class ExecutorConfig {
@Bean("logServiceExecutor")
public Executor logServiceExecutor() {
log.info("啟動(dòng) Log Service Executor");
ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 10,
5L, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(512),
new CustomizableThreadFactory("save-log-thread-"),
new ThreadPoolExecutor.DiscardPolicy());
return executor;
}
}
總結(jié)
- 從代碼可以看出,一共增加了兩部分代碼
- 1枫弟、線程池配置代碼(注意要加上
@EnableAsync
注解邢享,使異步生效) - 2、
LogServiceImpl
中save
方法增加了@Async("logServiceExecutor")
注解
- 1枫弟、線程池配置代碼(注意要加上
- 通過如上兩步媒区,簡單快捷實(shí)現(xiàn)方法異步處理驼仪,并且線程池與業(yè)務(wù)隔離
本文完。