关键词搜索

源码搜索 ×
×

Spring利用InitializingBean定义基于业务队列处理Handler

发布2021-09-06浏览463次

详情内容

目录

定义Handler类

定义类似面向过程编程的需求处理

泛型与面向对象的设计

利用Spring InitializingBean自动注入Handler

业务处理统一放入队列执行

任务管理API接口


在各种高效的编程框架中都有Handler身影,将一类业务通过Handler统一输出可以简化业务编程。比如:业务编号、业务持久化处理、业务异常等处理。

定义Handler类

  1. public interface ServiceHandler {
  2. ServiceType type();
  3. void execute(String data);
  4. void handleException(String data);
  5. }

定义类似面向过程编程的需求处理

项目结构:

面向过程服务:

  接口:

  1. /**
  2. * 面向过程的用户密码修改服务
  3. */
  4. public interface UserPwdUpdateService extends ServiceHandler {
  5. }

 实现:

  1. @Service
  2. public class UserPwdUpdateServiceImpl implements UserPwdUpdateService {
  3. @Override
  4. public ServiceType type() {
  5. return ServiceType.USER_PWD_UPDATE;
  6. }
  7. @Override
  8. public void execute(String data) {
  9. // 1.反序列化数据进行操作
  10. // 2.执行用户密码持久化操作
  11. }
  12. @Override
  13. public void handleException(String data) {
  14. // 1.反序列化数据进行操作
  15. // 2.用户密码相关数据回滚
  16. }
  17. }

上面是一个很面向过程的处理方式!!!

泛型与面向对象的设计

Handler接口泛型:

  1. /**
  2. * 业务处理泛型
  3. * @param <T>
  4. */
  5. public interface ServiceHandler<T> {
  6. ServiceType type();
  7. void execute(T data);
  8. void handleException(T data);
  9. }

泛型接口定义:

  1. /**
  2. * 用户密码修改服务
  3. */
  4. public interface UserPwdUpdateService extends ServiceHandler<User> {
  5. }

业务接口实现:

  1. @Service
  2. public class UserPwdUpdateServiceImpl implements UserPwdUpdateService {
  3. @Override
  4. public ServiceType type() {
  5. return ServiceType.USER_PWD_UPDATE;
  6. }
  7. @Override
  8. public void execute(User user) {
  9. // 执行用户密码持久化操作
  10. }
  11. @Override
  12. public void handleException(User user) {
  13. // 用户密码相关数据回滚
  14. }
  15. }

利用Spring InitializingBean自动注入Handler

  1. @Component
  2. public class ServiceTaskManger extends Thread implements InitializingBean {
  3. public static Map<ServiceType, ServiceHandler> handlers = new ConcurrentHashMap<>();
  4. @Autowired
  5. private Map<String, ServiceHandler<?>> handlerMap;
  6. @Override
  7. public void afterPropertiesSet() throws Exception {
  8. Preconditions.checkNotNull(handlerMap, "Handler 未初始化");
  9. for (ServiceHandler handler : handlerMap.values()) {
  10. handlers.put(handler.type(), handler);
  11. }
  12. }
  13. @Override
  14. public void run() {
  15. }
  16. }

业务处理统一放入队列执行

定义队列数据对象:

  1. /**
  2. * 数据类型
  3. * @param <T>
  4. */
  5. @Data
  6. public class AbstractService<T> {
  7. ServiceType type;
  8. T data;
  9. }

管理队列任务:

  1. /**
  2. * 业务处理任务管理器
  3. */
  4. @Component
  5. public class ServiceTaskManger extends Thread implements InitializingBean {
  6. public static Queue<AbstractService> queue = new LinkedBlockingDeque<>();
  7. private static Map<ServiceType, ServiceHandler> handlers = new ConcurrentHashMap<>();
  8. @Autowired
  9. private Map<String, ServiceHandler<?>> handlerMap;
  10. // 任务窃取线程池
  11. private ExecutorService executorService = Executors.newWorkStealingPool();
  12. @Override
  13. public void afterPropertiesSet() throws Exception {
  14. Preconditions.checkNotNull(handlerMap, "Handler 未初始化");
  15. for (ServiceHandler handler : handlerMap.values()) {
  16. handlers.put(handler.type(), handler);
  17. }
  18. }
  19. @Override
  20. public void run() {
  21. while (true){
  22. int count = queue.size();
  23. // 处理任务条件:队列不为空
  24. if(count>0){
  25. executorService.submit(new Runnable() {
  26. @Override
  27. public void run() {
  28. for (int i = 0; i < count; i++) {
  29. AbstractService service = queue.poll();
  30. ServiceHandler serviceHandler = handlers.get( service.getType());
  31. try{
  32. serviceHandler.execute(service.getData());
  33. }catch (Exception e){
  34. serviceHandler.handleException(service.getData());
  35. }
  36. }
  37. }
  38. });
  39. }
  40. }
  41. }
  42. }

任务管理API接口

  1. @RestController
  2. @RequestMapping("/services")
  3. public class ServiceTaskController {
  4. @RequestMapping("/account/save")
  5. public String accountSaveMoney(Account account){
  6. AccountService accountService = new AccountService();
  7. accountService.setType(ServiceType.ACCOUNT_SAVE_MONEY);
  8. accountService.setData(account);
  9. ServiceTaskManger.queue.add(accountService);
  10. return "success";
  11. }
  12. @RequestMapping("/account/withdraw")
  13. public String accountWithdrawMoney(Account account){
  14. AccountService accountService = new AccountService();
  15. accountService.setType(ServiceType.ACCOUNT_WITHDRAW_MONEY);
  16. accountService.setData(account);
  17. ServiceTaskManger.queue.add(accountService);
  18. return "success";
  19. }
  20. }

队列交互的接口适合跨系统异步业务。

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载