我們主要講職責鏈,但是其中會應用到反射技術;
首先,我們先了解職責鏈的使用場景;這裡舉一個例子:
上圖中有form1,2,3三種表單,會經過相同和不同的邏輯,且初始時表單的status=0;每處理完一個邏輯給form的status賦值當前邏輯的status;然後用戶需求有可能表單會在只經過邏輯1時,表單就不繼續走邏輯2、邏輯3;當滿足某一條件時又繼續執行邏輯2、邏輯3;我不確定你是否能理解我的意思,還是看代碼吧
我這裡給我實際開發的例子講解一下:
以上例子中每一個子類代表一個邏輯,我的數據來源于kafka中,
1,先抽象一個父類ChainHandler,將父類定義成為一個抽象的
父類中定義兩個方法,一個執行當前chain的方法,定義成抽象,這樣子類可以複習,第二個方法是執行下一個chain的方法,這個是所有方法都公用的,不用定義為抽象;
@Service public abstract class ChainHandler {
public abstract void exeProduce(ChainRequest request) throws Exception; public void doNext(ChainRequest request, ChainHandler currentChain) { ChainHandler nextChain = StartChain.getNextChain(currentChain); if (nextChain != null) { try { nextChain.exeProduce(request); } catch (Exception e) { e.printStackTrace(); } }
}
}
2.定義邏輯StartChain類,
@Component public class StartChain { @Autowired private List<ChainHandler> chainHandlers; private static List<ChainHandler> chains; /** * F3851884 2022/3/10 * @PostConstruct该注解被用来修饰一个非静态的void()方法。 * 被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行, * 并且只会被服务器执行一次。PostConstruct在构造函数之后执行,init()方法之前执行。 * */ @PostConstruct public void init() { chains = chainHandlers; } public static ChainHandler getNextChain(ChainHandler currentChain){ try { int currentChainPosition = (int) currentChain.getClass().getField("position").get(currentChain); for (ChainHandler chain : chains) { int chainPosition = (int) chain.getClass().getField("position").get(chain); if (currentChainPosition + 1 == chainPosition) { return chain; } } } catch (Exception e) { } return null; } public static void startChain(ChainRequest chainRequest) { int position = 1; if(chainRequest.getTableName().contains("won_jig_bid_detail_item") && chainRequest.getFormPosition() == 5){ }else{ position = chainRequest.getFormPosition(); } ChainHandler startChain = null; for (ChainHandler chain : chains) { try { if (Math.abs(position) == (int) chain.getClass().getField("position").get(chain)) { startChain = chain; break; } } catch (Exception e) { } } if (startChain != null) { try { startChain.exeProduce(chainRequest); } catch (Exception e) { e.printStackTrace(); } } } }
3.定義子類1:
@Service public class FdmApiChain extends ChainHandler{ protected final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private FdmApiConfig fdmApiConfig; @Autowired private RestTemplate restTemplate; public int position = 1; @Override public void exeProduce(ChainRequest request) { Boolean flag = true; if(request != null){ String remark = ""; List<Long> itemIds = request.getItemIds(); if(itemIds != null && itemIds.size() > 0){ //1.修改表單postion if(super.updateAbstractChainProceduInfo(request.getTableName(),itemIds,position)) { logger.info("文件:" + request.getFormId() + "開始調用fdm api" +position); //獲取fdm api String fdmUrl = fdmApiConfig.getFullUrl(); List<MouldInfo> mouldInfos = request.getMouldInfos(); if(mouldInfos != null && mouldInfos.size() > 0) { Map<String, List<MouldInfo>> map = new HashMap<>(); map.put("data", mouldInfos); String param = JSON.toJSONString(map); logger.info("data 調用fdm 參數" +param); //2.調用fdm接口 HttpResult httpResult = restTemplate.postForObject(fdmUrl, param, HttpResult.class); if (httpResult != null && httpResult.getData() != null && httpResult.getData().getSuccesData()!= null) { List<MouldInfo> succesData = httpResult.getData().getSuccesData(); logger.info("succesData:" + succesData.size() + "調用fdm api結果" +JSON.toJSONString(succesData)); DataResult data = new DataResult(); if (succesData != null && succesData.size() > 0) { data.setSuccesData(succesData); } else { flag = false; } List<MouldInfo> errData = httpResult.getData().getErrData(); if (errData != null && errData.size() > 0) { data.setErrData(errData); } request.setData(data); //3.添加log if (!flag) { remark = Constants.FDM_API_CHAIN_HTTP_ERR; } else { remark = Constants.FDM_API_CHAIN; } }else{ remark = Constants.FDM_API_CHAIN_HTTP_ERR; super.updateAbstractChainProceduInfo(request.getTableName(), itemIds, -1); } super.insertBatchLog(this.position,remark,request.getFormId(),itemIds); logger.info("文件:" + request.getFormId() + "完成調用fdm api" +position); Map<Long,String> mapSet = new HashMap<Long,String>(); for(MouldInfo mouldInfo:mouldInfos){ mapSet.put(mouldInfo.getItemId(),mouldInfo.getVendorCode()); logger.info("存放:" + mouldInfo.getItemId() + "----------------" +mouldInfo.getVendorCode()); } request.setMap(mapSet); //4.執行下一個子鏈 if (flag) { doNext(request, this); } } } }else{ remark = Constants.FDM_API_CHAIN_UPDATE_ERR; super.insertBatchLog(this.position,remark,request.getFormId(),itemIds); super.updateAbstractChainProceduInfo(request.getTableName(), itemIds, -1); } } } }