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

Posted boonya

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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";
    }

}

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

以上是关于Spring利用InitializingBean定义基于业务队列处理Handler的主要内容,如果未能解决你的问题,请参考以下文章

spring 中 InitializingBean 接口使用理解

spring常用接口 InitializingBean的作用

Spring Bean InitializingBean和DisposableBean实例

spring中InitializingBean接口使用理解

spring中InitializingBean接口使用理解

spring中InitializingBean接口使用理解