流程引擎核心代码

import java.util.HashMap;

/**
 * 每一个流程的全局上下文(静态内部类实现的单例)
 *
 * @author wb-zf300458 on 2018/1/30.
 */
public class FlowGlobalContext {
    private ThreadLocal nodeToShareData;

    private static class GlobalContextHolder {
        private static final FlowGlobalContext INSTANCE = new FlowGlobalContext();
    }

    private FlowGlobalContext() {
        nodeToShareData = new ThreadLocal();
        nodeToShareData.set(new HashMap<String,Object>());
    }

    public static final FlowGlobalContext getInstance() {
        return GlobalContextHolder.INSTANCE;
    }

    public ThreadLocal getNodeToShareData(){
        return nodeToShareData;
    }
}
----------------------------------------------------------------------------
 
 
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.util.Assert;

/**
 * 单例工厂(单例、单例注册表)
 *
 * @author wb-zf300458 on 2018/1/31.
 */
public class AbstractSingleBeanFactory {
    /**
     * 充当了Bean实例的缓存,实现方式和单例注册表相同
     */
    private final Map singletonCache;

    private AbstractSingleBeanFactory() {
        singletonCache = new ConcurrentHashMap(256);
    }

    private static class AbstractBeanFactoryHolder {
        private static final AbstractSingleBeanFactory INSTANCE = new AbstractSingleBeanFactory();
    }

    public static AbstractSingleBeanFactory getInstance() {
        return AbstractBeanFactoryHolder.INSTANCE;
    }

    public Object getBean(String name) throws Exception{
        Assert.notNull(name, "'name' must not be null");
        Object bean = this.singletonCache.get(name);
        if (bean == null) {
            //使用了代码锁定同步块,原理和同步方法相似,但是这种写法效率更高
            synchronized (this.singletonCache) {
                if (bean == null) {
                    bean = this.singletonCache.get(name);
                    if (bean == null) {
                        bean = Class.forName(name).newInstance();
                        this.singletonCache.put(name, bean);
                        return bean;
                    }
                }
            }
        }
        return bean;
    }
}
------------------------------------------------------------------------------
 
 
import com.wdk.finance.enums.BizTypeEnum;
import com.wdk.finance.node.flow.AbstractProcessFlow;
import com.wdk.finance.node.factory.bean.AbstractSingleBeanFactory;

/**
 * 流程工厂
 *
 * @author wb-zf300458 on 2018/1/27.
 */
public class FlowFactory {
    /**
     * 
     * @param bizType
     * @return
     */
    public AbstractProcessFlow getProcessFlow(String bizType) throws Exception {
        if (bizType == null) {
            return null;
        }
        if (String.valueOf(4).equals(bizType)) {
            return (AbstractProcessFlow)AbstractSingleBeanFactory.getInstance().getBean("com.wdk.finance.node.flow.PerformanceInvoiceProcessFlow");
        }
        return null;
    }
}

 
 
------------------------------------------------------------------------------
import com.wdk.finance.node.AbstractNode;

/**
 *
 *
 * @author wb-zf300458 on 2018/1/26.
 */
public class A extends AbstractNode {

    @Override
    public void execute() throws Exception {

    }
}

 
 
------------------------------------------------------------------------------
import com.wdk.finance.node.AbstractNode;

/**
 * 
 *
 * @author wb-zf300458 on 2018/1/25.
 */
public class B extends AbstractNode {

    @Override
    public void execute() throws Exception {

    }
}

 
 
------------------------------------------------------------------------------
 
 
import com.wdk.finance.node.AbstractNode;
import com.wdk.finance.node.context.FlowGlobalContext;

/**
 * 流程完毕移除该流程线程的参数值
 *
 * @author wb-zf300458 on 2018/1/30.
 */
public class RemoveThreadLocalValue extends AbstractNode {
    @Override
    public void execute() throws Exception {
       FlowGlobalContext.getInstance().getNodeToShareData().remove();
    }
}


 
 
------------------------------------------------------------------------------
import java.util.ArrayList;
import java.util.List;

import com.wdk.finance.node.AbstractNode;

/**
 * 抽象的处理流程
 *
 * @author wb-zf300458 on 2018/1/27.
 */
public abstract class AbstractProcessFlow implements Flow {
    List<AbstractNode> flowCombinations = new ArrayList<>();
}

 
 
------------------------------------------------------------------------------
import java.util.List;

import com.wdk.finance.node.AbstractNode;

/**
 * 流程接口
 *
 * @author wb-zf300458 on 2018/1/27.
 */
public interface Flow {
    /**
     * 获取流程组合
     *
     * @return
     */
    public List<AbstractNode> getFlowCombination() throws Exception;
}

 
 
------------------------------------------------------------------------------
import java.util.List;
import com.wdk.finance.node.AbstractNode;
import com.wdk.finance.node.factory.bean.AbstractSingleBeanFactory;

/**
 * 履约单据处理流程
 *
 * @author wb-zf300458 on 2018/1/27.
 */
public class PerformanceInvoiceProcessFlow extends AbstractProcessFlow{
    @Override
    public List<AbstractNode> getFlowCombination() throws Exception {
        flowCombinations.add((AbstractNode)AbstractSingleBeanFactory.getInstance().getBean("com.wdk.finance.node.flow.biz.A"));
        flowCombinations.add((AbstractNode)AbstractSingleBeanFactory.getInstance().getBean("com.wdk.finance.node.flow.biz.B"));
        flowCombinations.add((AbstractNode)AbstractSingleBeanFactory.getInstance().getBean("com.wdk.finance.node.flow.biz.RemoveThreadLocalValue"));
        return flowCombinations;
    }
}

 
 
------------------------------------------------------------------------------
public class MySingleton {
    private static class MySingletonHandler {
        private static MySingleton instance = new MySingleton();
    }

    private MySingleton() {}

    public static MySingleton getInstance() {
        return MySingletonHandler.instance;
    }
}

 
 
------------------------------------------------------------------------------
import com.wdk.finance.node.NodeHandler;
import com.wdk.finance.node.factory.bean.AbstractSingleBeanFactory;
import com.wdk.finance.node.factory.flow.FlowFactory;

/**
 * @author wb-zf300458 on 2018/1/31.
 */
public class NodeTest {
    public static void main(String[] args) throws Exception {
        FlowFactory flowFactory = (FlowFactory)AbstractSingleBeanFactory.getInstance().getBean("com.wdk.finance.node.factory.flow.FlowFactory");
        NodeHandler nodeHandler = (NodeHandler)AbstractSingleBeanFactory.getInstance().getBean("com.wdk.finance.node.NodeHandler");
        try {
            nodeHandler.handlerNode(flowFactory.getProcessFlow("4"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 
 
------------------------------------------------------------------------------
import com.wdk.finance.node.factory.bean.AbstractSingleBeanFactory;

/**
 * 测试多线程环境下,AbstractSingleBeanFactory创建的对象单例,是否正确
 *
 * @author wb-zf300458 on 2018/2/1.
 */
public class TestAbstractSingleBeanFactory extends Thread {
    @Override
    public void run() {
        try {
            while (true){
                System.out.println(
                    AbstractSingleBeanFactory.getInstance().getBean("com.wdk.finance.node.NodeHandler").hashCode());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        // 测试多线程下的
        TestAbstractSingleBeanFactory[] mts = new TestAbstractSingleBeanFactory[1000];
        for (int i = 0; i < mts.length; i++) {
            mts[i] = new TestAbstractSingleBeanFactory();
        }

        for (int j = 0; j < mts.length; j++) {
            mts[j].start();
        }
    }
}
------------------------------------------------------------------------------
 
 
import com.wdk.finance.node.context.FlowGlobalContext;

/**
 * 测试多线程环境下的静态内部类实现的单例
 */
public class TestThreadLocal extends Thread{
      
    @Override  
    public void run() {
        FlowGlobalContext.getInstance().getNodeToShareData().set(1);
        while (true){
            FlowGlobalContext globalContext = FlowGlobalContext.getInstance();
            ThreadLocal threadLocal = globalContext.getNodeToShareData();
            Integer i = (Integer)threadLocal.get();
            System.out.println(Thread.currentThread().getName()+","+i);
            if(null != i){
                i++;
            }
            threadLocal.set(i);
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
      
    public static void main(String[] args) {
        // 测试多线程下的
        TestThreadLocal[] mts = new TestThreadLocal[5];
        for(int i = 0 ; i < mts.length ; i++){
            mts[i] = new TestThreadLocal();
        }

        for (int j = 0; j < mts.length; j++) {
            mts[j].start();
        }
    }  
}  

------------------------------------------------------------------------------
 
 
import java.util.Map;

import com.wdk.finance.node.context.FlowGlobalContext;

/**
 * 流程相关的全局上下文工具类
 *
 * @author wb-zf300458 on 2018/2/1.
 */
public class FlowGlobalContextUtils {

    /**
     * 添加值到全局map里面
     *
     * @param key
     * @param value
     */
    public static void put(String key, Object value) {
        ((Map<String, Object>)FlowGlobalContext.getInstance().getNodeToShareData().get()).put(key, value);
    }

    /**
     * 从全局map里面取值
     *
     * @param key
     */
    public static Object get(String key) {
        return ((Map<String, Object>)FlowGlobalContext.getInstance().getNodeToShareData().get()).get(key);
    }
}

------------------------------------------------------------------------------
 
 
import java.util.Map;
import com.wdk.finance.node.context.FlowGlobalContext;

/**
 * 抽象节点(单例模式)
 *
 * @author wb-zf300458 on 2018/1/25.
 */
public abstract class AbstractNode implements Node {
    /**
     * 节点共享数据
     */
    protected Map<String, Object> nodeToShareData;

    /**
     * 外部调用(模板方法)
     * @return
     * @throws Exception
     */
    protected void invoke() throws Exception {
        beforeExecute();
        execute();
    }

    /**
     * 执行目标方法之前
     *
     * @return
     * @throws Exception
     */
    public void beforeExecute()throws Exception{
        // 获取节点共享的数据
        this.nodeToShareData = (Map<String, Object>)FlowGlobalContext.getInstance().getNodeToShareData().get();
    }
}

------------------------------------------------------------------------------
 
 
/**
 * 抽象的节点接口
 *
 * @author by wb-zf300458 on 2018/1/25.
 */
public interface Node {
    /**
     * 执行目标方法
     *
     * @return
     * @throws Exception
     */
    public void execute() throws Exception;
}

------------------------------------------------------------------------------
 
 
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.wdk.finance.node.context.FlowGlobalContext;
import com.wdk.finance.node.flow.AbstractProcessFlow;

/**
 * 抽象的节点处理者
 *
 * @author wb-zf300458 on 2018/1/25.
 */
public class NodeHandler {
    public void handlerNode(AbstractProcessFlow abstractProcessFlow) throws Exception{
        // 默认都要执行下一个节点
        ((Map<String, Object>)FlowGlobalContext.getInstance().getNodeToShareData().get()).put("nodeResult", true);
        List<AbstractNode> abstractNodes = abstractProcessFlow.getFlowCombination();
        try{
            Iterator abstractNodesIterator = abstractNodes.iterator();
            while (abstractNodesIterator.hasNext()){
                AbstractNode abstractNode = (AbstractNode)abstractNodesIterator.next();
                abstractNode.invoke();
                // 判断是否要继续执行下一个节点
                if (!((Boolean)abstractNode.nodeToShareData.get("nodeResult"))) {
                    if(abstractNodes.size()>1){
                        abstractNodes.get(abstractNodes.size()-1).invoke();
                    }
                    break;
                }
            }
        }catch (Exception e){
            if(abstractNodes.size()>1){
                abstractNodes.get(abstractNodes.size()-1).invoke();
            }
            throw e;
        }
    }
}
 

猜你喜欢

转载自blog.csdn.net/wssjdysf1/article/details/79231901