1.背景

在实际开发中,经常会遇到支付需求,当然就会有支付对账的需求….

2.项目结构

image.png

3.代码

线程池配置对象

  1. @Configuration
  2. @EnableAsync
  3. public class ExecutorConfig {
  4. /**
  5. * @return
  6. */
  7. @Bean
  8. public Executor asyncServiceExecutor() {
  9. ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
  10. //配置核心线程数
  11. executor.setCorePoolSize(30);
  12. //配置最大线程数
  13. executor.setMaxPoolSize(40);
  14. //配置队列大小
  15. executor.setQueueCapacity(99999);
  16. //配置线程池中的线程的名称前缀
  17. executor.setThreadNamePrefix("async-service-");
  18. // rejection-policy:当pool已经达到max size的时候,如何处理新任务
  19. // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
  20. executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
  21. //执行初始化
  22. executor.initialize();
  23. return executor;
  24. }
  25. }

controller代码

  1. @RestController
  2. public class BillController {
  3. @Autowired
  4. private IBillService billService;
  5. /**
  6. * 下载对账单
  7. *
  8. * @return
  9. */
  10. @RequestMapping("/api/downBill")
  11. public Object downBill() {
  12. Object result = billService.billDown();
  13. return "ok::" + result;
  14. }
  15. }

业务层代码-下载

  1. /**
  2. * @author 姿势帝-博客园
  3. * @address https://www.cnblogs.com/newAndHui/
  4. * @WeChat 851298348
  5. * @create 10/30 11:27
  6. * @description <p>
  7. * 以下载支付宝对账单为案例进行演示
  8. * 接口文档:https://opendocs.alipay.com/open/02ivbw
  9. * 关于支付支付课程可以查看:https://www.cnblogs.com/newAndHui/p/14258491.html
  10. * </p>
  11. */
  12. @Service
  13. @Slf4j
  14. public class BillServiceImpl implements IBillService {
  15. @Autowired
  16. private IOrderService orderService;
  17. @Override
  18. public Object billDown() {
  19. // 以下载支付宝对账单为案例进行演示
  20. // 这里模拟一个对账文件
  21. ExcelReader reader = ExcelUtil.getReader(FileUtil.file("F:\\test\\t1.xlsx"));
  22. // 分页取值,每页10条
  23. boolean flag = true;
  24. int pageIndex = 1;
  25. int pageSize = 10;
  26. int sum = 0;
  27. while (flag) {
  28. int startIndex = pageSize * (pageIndex - 1) + 1;
  29. int endIndex = startIndex + pageSize - 1;
  30. List<Map<String, Object>> list = reader.read(0, startIndex, endIndex);
  31. int size = list.size();
  32. if (size > 0) {
  33. sum += size;
  34. // 异步保存数据
  35. orderService.saveBillOrder(list);
  36. }
  37. if (list.size() < pageSize) {
  38. flag = false;
  39. } else {
  40. pageIndex++;
  41. }
  42. }
  43. return "共:" + sum + "交易记录";
  44. }
  45. }

业务层代码-保存

  1. @Service
  2. @Slf4j
  3. public class IOrderServiceImpl implements IOrderService {
  4. @Override
  5. @Async("asyncServiceExecutor")
  6. public void saveBillOrder(List<Map<String, Object>> list) {
  7. int size = list.size();
  8. log.info("保存数据:" + size);
  9. int i = 1;
  10. for (Map<String, Object> bIllOrder : list) {
  11. log.info("保存第:" + i + "/" + size + ",bIllOrder=" + bIllOrder);
  12. // 模拟保存耗时(0到5秒)
  13. ThreadUtil.sleepRandom();
  14. i++;
  15. log.info("数据保存完成");
  16. }
  17. }
  18. }

对账文件模板

image.png

4.测试

  1. @Test
  2. void downBill() {
  3. String url = "http://localhost:8001/api/downBill";
  4. HttpRequest request = HttpUtil.createGet(url);
  5. String response = request.execute().body();
  6. System.out.println(response);
  7. }

测试结果
image.png

5.完美!