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;
}
}
}