天下之事,必先处之难,而后易之。

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

目录

定义Handler类

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

泛型与面向对象的设计

利用Spring InitializingBean自动注入Handler

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

任务管理API接口


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

定义Handler类

public interface ServiceHandler {

    ServiceType type();

    void execute(String data);

    void handleException(String data);
}

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

项目结构:

面向过程服务:

  接口:

/**
 * 面向过程的用户密码修改服务
 */
public interface UserPwdUpdateService extends ServiceHandler {
}

 实现:

@Service
public class UserPwdUpdateServiceImpl implements UserPwdUpdateService {
    @Override
    public ServiceType type() {
        return ServiceType.USER_PWD_UPDATE;
    }

    @Override
    public void execute(String data) {
        // 1.反序列化数据进行操作
        // 2.执行用户密码持久化操作
    }

    @Override
    public void handleException(String data) {
        // 1.反序列化数据进行操作
        // 2.用户密码相关数据回滚
    }
}

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

泛型与面向对象的设计

Handler接口泛型:

/**
 * 业务处理泛型
 * @param <T>
 */
public interface ServiceHandler<T> {

    ServiceType type();

    void execute(T data);

    void handleException(T data);
}

泛型接口定义:

/**
 * 用户密码修改服务
 */
public interface UserPwdUpdateService extends ServiceHandler<User> {
}

业务接口实现:

@Service
public class UserPwdUpdateServiceImpl implements UserPwdUpdateService {
    @Override
    public ServiceType type() {
        return ServiceType.USER_PWD_UPDATE;
    }

    @Override
    public void execute(User user) {
        // 执行用户密码持久化操作
    }

    @Override
    public void handleException(User user) {
        // 用户密码相关数据回滚
    }
}

利用Spring InitializingBean自动注入Handler

@Component
public class ServiceTaskManger extends Thread implements InitializingBean {

    public static Map<ServiceType, ServiceHandler> handlers = new ConcurrentHashMap<>();

    @Autowired
    private Map<String, ServiceHandler<?>> handlerMap;

    @Override
    public void afterPropertiesSet() throws Exception {
        Preconditions.checkNotNull(handlerMap, "Handler 未初始化");
        for (ServiceHandler handler : handlerMap.values()) {
            handlers.put(handler.type(), handler);
        }
    }

    @Override
    public void run() {

    }
}

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

定义队列数据对象:

/**
 * 数据类型
 * @param <T>
 */
@Data
public class AbstractService<T> {

    ServiceType type;
    T data;
}

管理队列任务:

/**
 * 业务处理任务管理器
 */
@Component
public class ServiceTaskManger extends Thread implements InitializingBean {

    public static Queue<AbstractService> queue = new LinkedBlockingDeque<>();

    private static Map<ServiceType, ServiceHandler> handlers = new ConcurrentHashMap<>();

    @Autowired
    private Map<String, ServiceHandler<?>> handlerMap;

    // 任务窃取线程池
    private ExecutorService executorService = Executors.newWorkStealingPool();

    @Override
    public void afterPropertiesSet() throws Exception {
        Preconditions.checkNotNull(handlerMap, "Handler 未初始化");
        for (ServiceHandler handler : handlerMap.values()) {
            handlers.put(handler.type(), handler);
        }
    }

    @Override
    public void run() {
        while (true){
           int count = queue.size();
           // 处理任务条件:队列不为空
           if(count>0){
               executorService.submit(new Runnable() {
                   @Override
                   public void run() {
                       for (int i = 0; i < count; i++) {
                           AbstractService service = queue.poll();
                           ServiceHandler serviceHandler =  handlers.get( service.getType());
                           try{
                               serviceHandler.execute(service.getData());
                           }catch (Exception e){
                               serviceHandler.handleException(service.getData());
                           }
                       }
                   }
               });
           }
        }
    }
}

任务管理API接口

@RestController
@RequestMapping("/services")
public class ServiceTaskController {

    @RequestMapping("/account/save")
    public String accountSaveMoney(Account account){
        AccountService accountService = new AccountService();
        accountService.setType(ServiceType.ACCOUNT_SAVE_MONEY);
        accountService.setData(account);
        ServiceTaskManger.queue.add(accountService);
        return "success";
    }

    @RequestMapping("/account/withdraw")
    public String accountWithdrawMoney(Account account){
        AccountService accountService = new AccountService();
        accountService.setType(ServiceType.ACCOUNT_WITHDRAW_MONEY);
        accountService.setData(account);
        ServiceTaskManger.queue.add(accountService);
        return "success";
    }

}

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

posted @ 2023-02-13 20:18  boonya  阅读(10)  评论(0)    收藏  举报  来源
我有佳人隔窗而居,今有伊人明月之畔。
轻歌柔情冰壶之浣,涓涓清流梦入云端。
美人如娇温雅悠婉,目遇赏阅适而自欣。
百草层叠疏而有致,此情此思怀彼佳人。
念所思之唯心叩之,踽踽彳亍寤寐思之。
行云如风逝而复归,佳人一去莫知可回?
深闺冷瘦独自徘徊,处处明灯影还如只。
推窗见月疑是归人,阑珊灯火托手思忖。
庐居闲客而好品茗,斟茶徐徐漫漫生烟。

我有佳人在水之畔,瓮载渔舟浣纱归还。
明月相照月色还低,浅近芦苇深深如钿。
庐山秋月如美人衣,画堂春阁香气靡靡。
秋意幽笃残粉摇曳,轻轻如诉画中蝴蝶。
泾水潺潺取尔浇园,暮色黄昏如沐佳人。
青丝撩弄长裙翩翩,彩蝶飞舞执子手腕。
香带丝缕缓缓在肩,柔美体肤寸寸爱怜。
如水之殇美玉成欢,我有佳人清新如兰。
伊人在水我在一边,远远相望不可亵玩。