執(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ù)校驗
}
}