前言
不知道为啥,今天好像学不进去,没办法,那就继续编码吧。那么今天的话,加更一篇文章,那就是咱们这个任务执行器的实现。先前我们是实现到了这个部分,那么现在的话,我们实现的是这个部分。(ps:文末看到项目地址):
蓝色部分的内容,当然这个是完整的执行器,因此对于生命周期也会进行实现,不过在这里的话,发现先前的这个生命周期实在是冗余了,所以的话砍掉了部分内容,这部分主要是在这里:
这里的内容进行了简化,所以的话,使用起来看起来就没有那么吓人了。同样的这里还提供了这个简单实现的Handler,如果你需要高度定制化,那就直接实现这个接口,不要的话就继承这个handler类就可以了。当然在这个里面其实也没干啥:
执行器代理
okey,那么我们来看到我们的一个今天的内容吧,我们昨天的话是实现了这个,创建这个清单模板。那么接下来我们要做的就是通过这个清单模板,去创建代理执行对象,然后通过这个代理执行对象,去完成这个对应的操作。所以这里的话其实还是分为两个部分。
当然现在的话,我们实现的是这个代理对象。
代理对象
ok,我们先来看到我们的代理对象。
在这里的话我们有两个代理对象:
任务清单代理对象
首先的话,是我们的任务清单代理对象:
package com.huterox.todoscheduler.core.execute.proxy;
import com.huterox.todoscheduler.core.enumType.TodoListElementType;
import com.huterox.todoscheduler.core.enumType.TodoListStateType;
import com.huterox.todoscheduler.core.wapper.ListStateWrapper;
import com.huterox.todoscheduler.handler.*;
import java.io.Serializable;
import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;
/**
* 任务清单对象,这里记录的是基本的清单对象信息,
* */
public class TodoListExBean implements Serializable {
//任务清单类型
public TodoListElementType todoListElementType;
//任务清单的名字
public String todoListName;
//当前的状态,当然服务宕机恢复任务的时候,这个是一个很重要的凭证
public TodoListStateType todoListStateType;
//任务清单的状态信息
private ListStateWrapper stateWrapper;
//执行的次数,因为有失败重新执行的东东
private int exTimes;
/*
* 因为几个清单可能服务同一个用户,所以按照这个再给你分个类
* 对于ClsId相同的清单是顺序执行的,所以这个是最小颗粒度的操作
* */
public String ClsId;
TodoListErrorHandler todoListErrorHandler;
TodoListAfterHandler todoListAfterHandler;
TodoListBeforeCreateHandler todoListCreateCheckHandler;
private final Comparator keyComparator = new Comparator() {
@Override
public int compare(Integer key1, Integer key2) {
// 根据键的大小进行比较
return key1.compareTo(key2);
}
};
//对应执行的方法链路
private final Map sortedMap = new TreeMap(keyComparator);
public TodoListExBean() {
}
public TodoListExBean(TodoListElementType todoListElementType, String todoListName, TodoListErrorHandler todoListErrorHandler, TodoListAfterHandler todoListAfterHandler, TodoListBeforeCreateHandler todoListCreateCheckHandler) {
this.todoListElementType = todoListElementType;
this.todoListName = todoListName;
this.todoListErrorHandler = todoListErrorHandler;
this.todoListAfterHandler = todoListAfterHandler;
this.todoListCreateCheckHandler = todoListCreateCheckHandler;
}
@Override
public String toString() {
return "The TodoList name is:"+this.todoListName;
}
public int getExTimes() {
return exTimes;
}
public void setExTimes(int exTimes) {
this.exTimes = exTimes;
}
public TodoListExBean(String todoListName) {
this.todoListName = todoListName;
}
public TodoListStateType getTodoListStateType() {
return todoListStateType;
}
public void setTodoListStateType(TodoListStateType todoListStateType) {
this.todoListStateType = todoListStateType;
}
public ListStateWrapper getStateWrapper() {
return stateWrapper;
}
public void setStateWrapper(ListStateWrapper stateWrapper) {
this.stateWrapper = stateWrapper;
}
public Comparator getKeyComparator() {
return keyComparator;
}
public Map getSortedMap() {
return sortedMap;
}
public TodoListExBean(String todoListName, String clsId) {
this.todoListName = todoListName;
ClsId = clsId;
}
public TodoListElementType getTodoListElementType() {
return todoListElementType;
}
public void setTodoListElementType(TodoListElementType todoListElementType) {
this.todoListElementType = todoListElementType;
}
public String getTodoListName() {
return todoListName;
}
public String getClsId() {
return ClsId;
}
public void setClsId(String clsId) {
ClsId = clsId;
}
public void setTodoListName(String todoListName) {
this.todoListName = todoListName;
}
public TodoListErrorHandler getTodoListErrorHandler() {
return todoListErrorHandler;
}
public void setTodoListErrorHandler(TodoListErrorHandler todoListErrorHandler) {
this.todoListErrorHandler = todoListErrorHandler;
}
public TodoListAfterHandler getTodoListAfterHandler() {
return todoListAfterHandler;
}
public void setTodoListAfterHandler(TodoListAfterHandler todoListAfterHandler) {
this.todoListAfterHandler = todoListAfterHandler;
}
public TodoListBeforeCreateHandler getTodoListCreateCheckHandler() {
return todoListCreateCheckHandler;
}
public void setTodoListCreateCheckHandler(TodoListBeforeCreateHandler todoListCreateCheckHandler) {
this.todoListCreateCheckHandler = todoListCreateCheckHandler;
}
}
任务清单执项对象
然后的话,是我们的一个任务清单的执行项:
package com.huterox.todoscheduler.core.execute.proxy;
import com.huterox.todoscheduler.core.enumType.TodoItemElementType;
import com.huterox.todoscheduler.core.enumType.TodoItemStateType;
import com.huterox.todoscheduler.core.wapper.ItemStateWrapper;
import com.huterox.todoscheduler.handler.*;
import java.io.Serializable;
import java.lang.reflect.Method;
/**
* 任务清单对应的Item,这里记录的是这个Item基本的信息
* */
public class TodoItemExBean implements Serializable {
//任务清单项类型
public TodoItemElementType todoItemElementType;
//任务执行顺序
public int order;
//这是第几个清单的方法
private int idx;
//实例对象
private Object wrapperInstance;
//对应的class
private Class wrapperClass;
//对应的方法
private Method wrapperMethod;
//当前的状态,当然服务宕机恢复任务的时候,这个是一个很重要的凭证
public TodoItemStateType todoItemStateType;
TodoItemBeforeCreateHandler todoItemCreateHandler;
TodoItemAfterRunningHandler todoItemAfterRunningHandler;
TodoItemBeforeRunningHandler todoItemBeforeRunningHandler;
TodoItemErrorHandler todoItemErrorHandler;
private ItemStateWrapper stateWrapper;
public TodoItemExBean() {
//初始化的时候就进行创建
this.stateWrapper = new ItemStateWrapper();
}
public TodoItemExBean(int order) {
this.order = order;
}
public ItemStateWrapper getStateWrapper() {
return stateWrapper;
}
public void setStateWrapper(ItemStateWrapper stateWrapper) {
this.stateWrapper = stateWrapper;
}
public Object getWrapperInstance() {
return wrapperInstance;
}
public void setWrapperInstance(Object wrapperInstance) {
this.wrapperInstance = wrapperInstance;
}
public Class getWrapperClass() {
return wrapperClass;
}
public void setWrapperClass(Class wrapperClass) {
this.wrapperClass = wrapperClass;
}
public Method getWrapperMethod() {
return wrapperMethod;
}
public void setWrapperMethod(Method wrapperMethod) {
this.wrapperMethod = wrapperMethod;
}
public TodoItemStateType getTodoItemStateType() {
return todoItemStateType;
}
public void setTodoItemStateType(TodoItemStateType todoItemStateType) {
this.todoItemStateType = todoItemStateType;
}
public int getIdx() {
return idx;
}
public void setIdx(int idx) {
this.idx = idx;
}
@Override
public String toString() {
return "the order is "+this.order;
}
public TodoItemExBean(TodoItemElementType todoItemElementType, int order, TodoItemBeforeCreateHandler todoItemCreateHandler, TodoItemAfterRunningHandler todoItemAfterRunningHandler, TodoItemBeforeRunningHandler todoItemBeforeRunningHandler, TodoItemErrorHandler todoItemErrorHandler) {
this.todoItemElementType = todoItemElementType;
this.order = order;
this.todoItemCreateHandler = todoItemCreateHandler;
this.todoItemAfterRunningHandler = todoItemAfterRunningHandler;
this.todoItemBeforeRunningHandler = todoItemBeforeRunningHandler;
this.todoItemErrorHandler = todoItemErrorHandler;
}
public TodoItemElementType getTodoItemElementType() {
return todoItemElementType;
}
public void setTodoItemElementType(TodoItemElementType todoItemElementType) {
this.todoItemElementType = todoItemElementType;
}
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
public TodoItemBeforeCreateHandler getTodoItemCreateHandler() {
return todoItemCreateHandler;
}
public void setTodoItemCreateHandler(TodoItemBeforeCreateHandler todoItemCreateHandler) {
this.todoItemCreateHandler = todoItemCreateHandler;
}
public TodoItemAfterRunningHandler getTodoItemAfterRunningHandler() {
return todoItemAfterRunningHandler;
}
public void setTodoItemAfterRunningHandler(TodoItemAfterRunningHandler todoItemAfterRunningHandler) {
this.todoItemAfterRunningHandler = todoItemAfterRunningHandler;
}
public TodoItemBeforeRunningHandler getTodoItemBeforeRunningHandler() {
return todoItemBeforeRunningHandler;
}
public void setTodoItemBeforeRunningHandler(TodoItemBeforeRunningHandler todoItemBeforeRunningHandler) {
this.todoItemBeforeRunningHandler = todoItemBeforeRunningHandler;
}
public TodoItemErrorHandler getTodoItemErrorHandler() {
return todoItemErrorHandler;
}
public void setTodoItemErrorHandler(TodoItemErrorHandler todoItemErrorHandler) {
this.todoItemErrorHandler = todoItemErrorHandler;
}
}
处理handler对象
然后在这里的话,可以看到这里还有很多Handler,这个东西,就是我们一开始看到的东西,因为我们接下来要实现一个完整的代理执行周期,因此我们必须拿到这些东西。然后进行执行。这里的话我们可以先看到我们的一个执行:
所以的话,这里要注意,我们为什么这里有那么多Handler。
状态对象
之后的话,是我们的一个状态,在执行方法的时候,我们可以保持到清单的一个状态,还有每一个清单项的状态,你都可以拿到。那么这里的话,主要是因为这个接口:
你要实现的方法里面带有这个,然后在后期执行代码的时候,我们会把这个对象给你,你可以看到这个:
代理工厂
okey,那么接下来就是我们的代理工厂的实现了。
那么同样的,我们当然有两个代理工厂了,一个是关于任务清单的,还有一个是关于任务项的。
任务清单代理工厂
先来看到我们的任务清单代理工厂:
package com.huterox.todoscheduler.core.execute;
import com.huterox.todoscheduler.core.enumType.TodoListStateType;
import com.huterox.todoscheduler.core.execute.proxy.TodoItemExBean;
import com.huterox.todoscheduler.core.execute.proxy.TodoListExBean;
import com.huterox.todoscheduler.core.global.TodoListTemplateMap;
import com.huterox.todoscheduler.core.wapper.TodoItemMethodWrapper;
import com.huterox.todoscheduler.core.wapper.TodoListWrapper;
import com.huterox.todoscheduler.exception.TodoListException;
import com.huterox.todoscheduler.handler.TodoListBeforeCreateHandler;
import java.io.Serializable;
import java.util.Map;
/**
* 创建真正的任务执行清单对象,
* 通过这个ToDoListBean的信息来进行创建
* */
public class TodoListFactory implements Serializable {
/**
* 创建可以执行的清单对象,然后对执行器就会执行这个对象,执行的是TodoListExBean
* 如果返回结果为null,说明连这个清单都没有
* */
public static TodoListExBean getInstance(String listName) {
TodoListExBean todoListExBean = new TodoListExBean();
if(!TodoListTemplateMap.getInstance().containKey(listName)){
new TodoListException("未找到任务清单失败:"+listName,-1).printStackTrace();
todoListExBean.setTodoListStateType(TodoListStateType.CreatFailed);
return null;
}
//先获取到清单的模板
TodoListWrapper todoListTemplate = TodoListTemplateMap.getInstance().get(listName);
todoListExBean.setTodoListName(todoListTemplate.getTodoListName());
todoListExBean.setTodoListAfterHandler(todoListTemplate.getTodoListAfterHandler());
todoListExBean.setTodoListCreateCheckHandler(todoListTemplate.getTodoListCreateCheckHandler());
todoListExBean.setTodoListErrorHandler(todoListTemplate.getTodoListErrorHandler());
//执行创建前的方法
if(todoListExBean.getTodoListCreateCheckHandler()!=null){
try {
TodoListBeforeCreateHandler todoListCreateCheckHandler = todoListExBean.getTodoListCreateCheckHandler();
//先执行这个获取ClsID的方法
try {
String s = todoListCreateCheckHandler.setCIds();
if(!("".equals(s))){
todoListExBean.setClsId(s);
}else {
todoListExBean.setClsId("");
}
}catch (Exception e){
e.printStackTrace();
todoListExBean.setTodoListStateType(TodoListStateType.CreatFailed);
return todoListExBean;
}
}catch (Exception exception){
exception.printStackTrace();
todoListExBean.setTodoListStateType(TodoListStateType.CreatFailed);
return todoListExBean;
}
}
//遍历模板,然后将可执行的清单项放在我们的这个TodoListBeanEx的执行项目里面
Map sortedMapEx = todoListExBean.getSortedMap();
Map sortedMap = todoListTemplate.getSortedMap();
for(Map.Entry sortedMapEntry:sortedMap.entrySet()){
TodoItemMethodWrapper mapEntryValue = sortedMapEntry.getValue();
Integer key = sortedMapEntry.getKey();
TodoItemExBean instance = TodoItemFactory.getInstance(mapEntryValue,todoListExBean);
if(instance==null){
//如果这个清单项创建失败,那也是失败
return null;
}
sortedMapEx.put(key,instance);
}
//此时创建完毕,但是这里每一个方法如何执行,也就是清单项是调度器考虑的事情了
return todoListExBean;
}
}
通过这个来创建到我们的清单
清单任务项代理工厂
之后是这个,一个清单里面包含了很多的这个执行项,因为本质上,一个执行项就是一个类方法嘛。
package com.huterox.todoscheduler.core.execute;
import com.huterox.todoscheduler.annotate.*;
import com.huterox.todoscheduler.core.enumType.TodoItemElementType;
import com.huterox.todoscheduler.core.execute.proxy.TodoItemExBean;
import com.huterox.todoscheduler.core.execute.proxy.TodoListExBean;
import com.huterox.todoscheduler.core.wapper.TodoItemMethodWrapper;
import com.huterox.todoscheduler.handler.TodoItemAfterRunningHandler;
import com.huterox.todoscheduler.handler.TodoItemBeforeCreateHandler;
import com.huterox.todoscheduler.handler.TodoItemBeforeRunningHandler;
import com.huterox.todoscheduler.handler.TodoItemErrorHandler;
import java.io.Serializable;
import java.lang.reflect.Method;
/**
* 负责将方法解析出来
* */
public class TodoItemFactory implements Serializable {
//当这个方法返回null的时候,说明创建失败
public static TodoItemExBean getInstance(TodoItemMethodWrapper todoItemMethodWrapper, TodoListExBean todoListExBean){
TodoItemExBean todoItemExBean = new TodoItemExBean();
todoItemExBean.setOrder(todoItemMethodWrapper.getOrder());
todoItemExBean.setTodoItemElementType(todoItemMethodWrapper.getTodoItemElementType());
todoItemExBean.setIdx(todoItemMethodWrapper.getIdx());
todoItemExBean.setWrapperMethod(todoItemMethodWrapper.getWrapperMethod());
todoItemExBean.setWrapperClass(todoItemMethodWrapper.getWrapperClass());
todoItemExBean.setWrapperInstance(todoItemMethodWrapper.getWrapperInstance());
//解析注解
Method wrapperMethod = todoItemMethodWrapper.getWrapperMethod();
wrapperMethod.setAccessible(true);
if(wrapperMethod.isAnnotationPresent(TodoItemBeforeCreate.class)){
//这个时候要先去执行一下这个初始化创建的代码
TodoItemBeforeCreate annotationTodoItemBeforeCreate = wrapperMethod.getAnnotation(TodoItemBeforeCreate.class);
Class[] todoItemBeforeCreates = annotationTodoItemBeforeCreate.todoItemBeforeCreates();
Class todoItemBeforeCreateHandlerClass = todoItemBeforeCreates[todoItemExBean.getIdx()];
try {
TodoItemBeforeCreateHandler todoItemBeforeCreateHandler = todoItemBeforeCreateHandlerClass.newInstance();
//把这个状态Wrapper给它,这个时候是直接执行这个家伙
try {
todoItemBeforeCreateHandler.concierge(todoItemExBean.getStateWrapper(),todoListExBean.getStateWrapper());
}catch (Exception e){
//判断一下类型,是属于哪一种,是那种可以跳过执行的清单项
if(todoItemExBean.getTodoItemElementType()== TodoItemElementType.CONTINUTEITEM){
//继续happy执行往下走继续
System.err.println("当前清单项创建失败执行方法:"+wrapperMethod.getName()
+"对应的类为:"+todoItemExBean.getWrapperClass().getName()
);
e.printStackTrace();
}else {
//不能继续往下happy了,直接先执行修复
try {
todoItemBeforeCreateHandler.repair(todoItemExBean.getStateWrapper(),todoListExBean.getStateWrapper());
}catch (Exception e1){
//连修复都G了,没了
e1.printStackTrace();
}
return null;
}
//还是必须要强制执行的清单项
e.printStackTrace();
}
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
if(wrapperMethod.isAnnotationPresent(TodoItemBefore.class)){
TodoItemBefore annotationTodoItemBefore = wrapperMethod.getAnnotation(TodoItemBefore.class);
Class[] todoItemBeforeRunningHandlerClasses = annotationTodoItemBefore.todoItemBefores();
Class todoItemBeforeRunningHandlerClass = todoItemBeforeRunningHandlerClasses[todoItemExBean.getIdx()];
TodoItemBeforeRunningHandler todoItemBeforeRunningHandler = null;
try {
todoItemBeforeRunningHandler = todoItemBeforeRunningHandlerClass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
return null;
}
todoItemExBean.setTodoItemBeforeRunningHandler(todoItemBeforeRunningHandler);
}
if(wrapperMethod.isAnnotationPresent(TodoItemAfterHandler.class)){
TodoItemAfterHandler annotationTodoItemAfterHandler = wrapperMethod.
getAnnotation(TodoItemAfterHandler.class);
Class[] todoItemAfterRunningHandleClasses = annotationTodoItemAfterHandler.
todoItemAfterHandlers();
Class todoItemAfterRunningHandleClass = todoItemAfterRunningHandleClasses[todoItemExBean.getIdx()];
TodoItemAfterRunningHandler todoItemAfterRunningHandler = null;
try {
todoItemAfterRunningHandler = todoItemAfterRunningHandleClass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
return null;
}
todoItemExBean.setTodoItemAfterRunningHandler(todoItemAfterRunningHandler);
}
if(wrapperMethod.isAnnotationPresent(TodoItemError.class)) {
TodoItemError annotationTodoItemError = wrapperMethod.getAnnotation(TodoItemError.class);
Class[] todoItemErrorHandlerClasses = annotationTodoItemError.todoItemErrors();
Class todoItemErrorHandlerClass = todoItemErrorHandlerClasses[todoItemExBean.getIdx()];
TodoItemErrorHandler todoItemErrorHandler = null;
try {
todoItemErrorHandler = todoItemErrorHandlerClass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
return null;
}
todoItemExBean.setTodoItemErrorHandler(todoItemErrorHandler);
}
//此时我们的清单项封装实例化完毕
return todoItemExBean;
}
}
总结
那么到这里,我们就完成了这个任务清单的代理实现。当然这里面用到了很多的一些Wrapper类,但是核心就是上面说到的东西。
之后的话,通过差不多天半的开发:我们(团队成员the only one is me) 完成了这个项目的开发,现在的话在写这个开发教程。所以今天的话,大概是有3更。本来是说慢慢做的,但是发现有这个事情,然后每天写一点的话不连贯。重新想的时候好慢,所以没有办法,今天是特意专门拿出一天的时间拿过来开发。因为昨天干到两点,没啥精神,考研的话看不下去。一直有心事,压在身上很不舒服。
然后项目地址:gitee.com/Huterox/hto… 当然这里面还有很多工作要做,只是核心功能做好了。