一、定义工厂管理类
/**
* 订单业务管理类
* @author yunpeng.zhao
* @version $Id PayMethodManager.java, v 0.1 2018-02-04 上午11:03 yp-tc-m-2651 Exp $$
*/
public class OrderBizFactory {
private static final Logger logger = LoggerFactory.getLogger(OrderBizFactory.class);
private static Map<String,OrderBiz> payBizMap = new ConcurrentHashMap<String, OrderBiz>();
/**
* 得到订单实例
* @param orderType
* @return
*/
public static OrderBiz getOrderBiz(OrderTypeEnum orderType){
try {
if (orderType !=null){
return payBizMap.get(orderType.name());
}else {
logger.warn("订单类型为空,无法获取订单实例");
throw BalanceGrowException.ORDER_GET_ORDER_BIZ_EXCEPTION;
}
} catch (Exception e) {
logger.error("获取支付业务类出现异常:{}",e);
throw BalanceGrowException.ORDER_GET_ORDER_BIZ_EXCEPTION;
}
}
/**
* 提供的对外接口,以方便运行时添加
* @param payBiz
* @param payBiz
*/
public static void addOrderBizService(String payBiz,OrderBiz orderBiz){
payBizMap.put(payBiz,orderBiz);
}
}
二、抽象出处理接口
public interface OrderBiz {
/**
* 订单处理入口,增加redis并发请求锁
* @param requestBean
* @return
*/
OrderResponseBean process(final OrderRequestBean requestBean) ;
/**
* 异步回调处理入口
* @param callbackParam
* @return
*/
BaseResponseDTO callback(Map callbackParam);
}
三、定义步骤地模板方法抽象类
/**
* 订单请求处理类
* @author yunpeng.zhao
*/
public abstract class AbstractOrderBiz implements OrderBiz {
private static Logger logger = LoggerFactory.getLogger(AbstractOrderBiz.class);
@Autowired
private AccountInfoService accountInfoService;
/**
* 订单业务请求处理入口
* @param requestBean
*/
@Override
public OrderResponseBean process(final OrderRequestBean requestBean) {
OrderResponseBean orderResponseBean = new OrderResponseBean();
//1.加锁
//防并发redisKey
RedisLock redisLock = createRedisLock(requestBean);
try {
if (redisLock.lock()) {
//校验订单
checkOrder(requestBean);
//2.校验账户
checkAccount(requestBean);
//3.创建记录
addOrder(requestBean);
}else {
logger.info("订单请求未获取到redis锁,业务方请求号:{}",requestBean.getRequestFlowNo());
}
} catch (BalanceGrowException e) {
throw e;
} finally{
redisLock.unlock();
}
orderProcess(requestBean,orderResponseBean);
//是否通知业务方
boolean isNeedCallBack = isNeedCallback(requestBean);
if(isNeedCallBack){
//异步通知业务方
asyncCallBack(requestBean);
}
return orderResponseBean;
}
/**
* 是否异步通知业务方
* @return
*/
protected boolean isNeedCallback(OrderRequestBean requestBean){
//默认实现不回调
return false;
}
/**
* 银行订单异步回调处理入口
* @param callbackParam
* @return
*/
@Override
public BaseResponseDTO callback(Map callbackParam) {
BaseResponseDTO responseDTO = new BaseResponseDTO("0001","回调失败");
OrderRequestBean orderRequestBean = new OrderRequestBean();
//资金流水号
String fundFlowNo = (String)callbackParam.get("tran_no");
//1.校验交易订单是否已经成功
boolean isReturn = checkOrderByCallback(orderRequestBean,fundFlowNo,responseDTO);
if (isReturn){
return responseDTO;
}
//2.更新订单
updateOrderByCallback(orderRequestBean,callbackParam,responseDTO);
return responseDTO;
}
/**
* 当订单状态不为成功时
* 更新银行异步回调的订单
* @param orderRequestBean
* @param callbackParam
* @param responseDTO
*/
protected abstract void updateOrderByCallback(OrderRequestBean orderRequestBean, Map callbackParam, BaseResponseDTO responseDTO);
/**
* 校验异步回调的订单是否成功,
* 不成功时,将订单放到OrderRequestBean中,供后续更新
* @param orderRequestBean
* @param fundFlowNo
* @return
*/
protected abstract boolean checkOrderByCallback(OrderRequestBean orderRequestBean, String fundFlowNo,BaseResponseDTO responseDTO);
/**
* 创建redis锁
* @param requestBean
* @return
*/
private RedisLock createRedisLock(OrderRequestBean requestBean) {
return new RedisLock(BalanceGrowConstant.REDIS_KEY_PREFIX_CONSTANTS_ORDER
+requestBean.getBizSystem()+requestBean.getRequestFlowNo());
}
/**
* 校验订单是否存在
* @param requestBean
*/
protected abstract void checkOrder(OrderRequestBean requestBean);
/**
* 校验虚拟账户是否存在
* @param requestBean
*/
protected abstract void checkAccount(OrderRequestBean requestBean);
/**
* 创建不同类型的交易订单
* @param requestBean
*/
protected abstract void addOrder(OrderRequestBean requestBean);
/**
* 处理不同类型的交易订单,
* 调用银行不同的接口
* @param requestBean
*/
protected abstract void orderProcess(OrderRequestBean requestBean,OrderResponseBean orderResponseBean);
/**
* 异步化处理通知业务方
* 只有成功、失败地订单才回调
* @param requestBean
*/
public abstract void asyncCallBack(OrderRequestBean requestBean);
/**
* 校验虚拟账户是否存在
* @param accountNo
*/
protected AccountInfoEntity queryAccount(String accountNo) {
//2.校验账户是否存在
AccountInfoEntity accountInfoEntity =accountInfoService.queryByAccountNo(accountNo);
if(accountInfoEntity == null){
logger.warn("虚拟账户:{}不存在!",accountNo);
throw BalanceGrowException.ORDER_ACCOUNT_IS_NOT_EXIST_EXCEPTION;
}
return accountInfoEntity;
}
}
四、子类只需要继承并实现具体地处理步骤,就行,从而处理不同类型地订单