并發(fā) List、Map的應(yīng)用場景(執(zhí)行引擎設(shè)計)

執(zhí)行引擎設(shè)計

1:sql表
CREATE TABLE `job_executor_map` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主鍵',
  `enabled` tinyint(3) NOT NULL DEFAULT '1' COMMENT '1 - 可用,2 - 不可用',
  `job_type` varchar(32) NOT NULL DEFAULT '' COMMENT '業(yè)務(wù)類型',
  `executor` varchar(64) NOT NULL DEFAULT '' COMMENT '執(zhí)行器',
  `executor_name` varchar(32) NOT NULL DEFAULT '' COMMENT '執(zhí)行器名稱',
  `sort` tinyint(3) NOT NULL DEFAULT '0' COMMENT '執(zhí)行器的執(zhí)行順序',
  `create_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '創(chuàng)建時間',
  `modify_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '修改時間',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8 COMMENT='業(yè)務(wù)流程配置';

對應(yīng)的實體類:JobExecutorMapModel 、 JobExecutorMapDaoImpl、JobExecutorMapDao

2:執(zhí)行引擎(可支持回滾的)
@Service
public class ExecuteEngine {
    // 執(zhí)行器工廠,可根據(jù)job類型,撈出對應(yīng)的所有順序執(zhí)行的執(zhí)行器
    @Autowired
    private ExecutorFactory executorFactory;
    private Logger logger = LoggerFactory.getLogger(ExecuteEngine.class);
  
    /**
     * 
     * @param request
     */
    public ExecuteResult doExecute(ExecuteRequest request) {
        // 執(zhí)行器上下文環(huán)境
        EngineContext context = new EngineContext();
        // 根據(jù)job類型,獲取執(zhí)行器列表
        List<Executor> list = executorFactory.getExecutorList(request.getJobType());
        // 記錄已經(jīng)執(zhí)行過的執(zhí)行器,若失敗了,可以回滾
        Stack<Executor> executorStack = new Stack<>();
    for (Executor executor : list) {
                executorStack.push(executor);
                // 執(zhí)行執(zhí)行器的doExecute方法
        executor.doExecute(context, request);
                // 失敗,則回滾
                if(context.isError()){
                    rollBack(executorStack, request);
                }
    }
        ExecuteResult result = new ExecuteResult();
        result.setResultObject(context.getData(ContextDataKeyEnum.EXECUTE_RESULT));
        return result;
    }
    
    public void reload() {
        processFactory.reload();
    }
}
3:執(zhí)行器工廠
/**
 * 執(zhí)行器工廠
 */
@Service
public class ExecutorFactory {

    private Logger logger = LoggerFactory.getLogger(ExecutorFactory.class);
    @Autowired
    private JobExecutorMapDao jobExecutorMapDaoImpl;

    /**
     * executor列表,map的key對應(yīng)job類型,value對應(yīng)任務(wù)的所有順序的執(zhí)行器
     */
    private Map<String, List<Executor>> executorMap;

    /**
     * 按照業(yè)務(wù)類型查找流程定義
     */
    public List<Executor> getExecutorList(JobTypeEnum jobType) {
        // 按照業(yè)務(wù)類型查找流程定義
        List<Executor> result = this.executorMap.get(jobType.name());
        if (result == null) {
            logger.error("業(yè)務(wù)類型無對應(yīng)的執(zhí)行器,jobType=" + jobType.name());
        }
        return result;
    }

    public void reload() {
        executorMap = null;
        load();
    }
        // 執(zhí)行工廠加載到bean中,初始化executorMap
    @PostConstruct
    public synchronized void load() {
        if (executorMap == null) {
            executorMap = Maps.newConcurrentMap();
        }

        Map<String, List<JobExecutorMapModel>> executorModelMap = getBizExecutorMap();
        for (Map.Entry<String, List<JobExecutorMapModel>> entry : executorModelMap.entrySet()) {
            List<JobExecutorMapModel> models = entry.getValue();
                        // 對執(zhí)行器進行排序
            Collections.sort(models, (BizExecutorMapModel o1, BizExecutorMapModel o2) 
 -> {
                return o1.getSort().intValue() - o2.getSort().intValue();
            });
            List<Executor> executor = Lists.newArrayList();
            for (BizExecutorMapModel model : models) {
                                // 根據(jù)反射,獲取對應(yīng)的執(zhí)行器的javaBean
                executor.add((Executor) SpringBeanUtil.getBean(model.getExecutor()));
            }
            executorMap.put(entry.getKey(), executor);
        }
        logger.info("[ExecutorFactory] executorMap:{}", executorMap);

    }

    private Map<String, List<JobExecutorMapModel>> getBizExecutorMap() {
        Map<String, List<JobExecutorMapModel>> executorMap = Maps.newConcurrentMap();
                // 從job_executor_map里面,撈出所有的JobExecutorMapModel
        List<JobExecutorMapModel> bizExecutorMapModels = jobExecutorMapDaoImpl.queryAllExecutorMap();
               // 基于JobType進行分類
        for (BizExecutorMapModel bizExecutorMapModel : bizExecutorMapModels) {
            List<JobExecutorMapModel> bems = executorMap.get(bizExecutorMapModel.getJobType());
            if (CollectionUtils.isEmpty(bems)) {
                bems = Lists.newArrayList();
            }
            bems.add(JobExecutorMapModel);
            executorMap.put(bizExecutorMapModel.getJobType(), bems);
        }
        return executorMap;
    }

}

4:執(zhí)行器接口
public interface Executor {
    public void doExecute(EngineContext engineContext, ExecuteRequest request);
5:執(zhí)行器實現(xiàn)類(可細分為 ExecuteChecker、ExecuteAction兩個抽象類)
/**
* 執(zhí)行一些參數(shù)校驗邏輯的執(zhí)行器
**/
public abstract class ExecuteChecker implements Executor {
    @Override
    public final void doExecute(EngineContext engineContext, ExecuteRequest request) {
        doCheck(engineContext, request);
    }
    /**
     * doCheck方法,執(zhí)行一些參數(shù)校驗邏輯
     */
    public abstract void doCheck(EngineContext engineContext, ExecuteRequest request);

}

/**
* 執(zhí)行具體的業(yè)務(wù)邏輯的執(zhí)行器
**/
public abstract class ExecuteAction implements Executor { 
    @Override
    public final  void doExecute(EngineContext engineContext, ExecuteRequest request) {
        doAction(engineContext,request);
    }
    /**
     * doAction方法,執(zhí)行具體的業(yè)務(wù)邏輯
     */
    public abstract void doAction(EngineContext engineContext, ExecuteRequest request);
}
6:具體的執(zhí)行器實現(xiàn)類
@Service
public class action1 extends ExecuteAction {
    private Logger logger = LoggerFactory.getLogger(action1.class);
    @Autowired

    @Override
    public void doAction(EngineContext engineContext, ExecuteRequest request) {
        ......
    }
}

@Service
public class checker1 extends ExecuteChecker {
    private Logger logger = LoggerFactory.getLogger(checker1.class);
    /**
     * @param engineContext
     * @param request
     */
    @Override
    public void doCheck(EngineContext engineContext, ExecuteRequest request) {
        // 針對業(yè)務(wù)類型的參數(shù)校驗
        ......
        // 特殊參數(shù)校驗
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容