1. メリットとデメリット
利点:
プロセッサ間の結合が減少し、各プロセッサは自身の内部ロジックの処理のみに集中し、それを次のプロセッサに渡します。
特定の上流と下流の呼び出し関係に注意を払う必要はなく、責任チェーンを組み立てるときに、次のプロセッサの呼び出し関係が Spring の特性を通じて動的に挿入されます。
@Order アノテーションにより、プロセッサ間の呼び出し順序を柔軟に調整できます。
短所:
プログラムが複雑になる 適切に評価して使用する必要がある デザイン パターンをデザイン パターンのために使用することはできない
2. 使用する
1. ビジネスで使用される基本クラスを定義する
import java.io.Serializable;
/**
* @author lishuzhen
* @createTime 2022年06月19日 22:40:00
*/
public class ResultDTO implements Serializable {
private String msg;
public static ResultDTO ok(){
return new ResultDTO();
}
public ResultDTO() {
msg = "ok";
}
public String getMsg() {
return msg;
}
}
/**
* @author lishuzhen
* @createTime 2022年06月19日 22:15:00
*/
public class OrderDTO {
private String orderNo;
public String getOrderNo() {
return orderNo;
}
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
}
2. 抽象プロセッサ インターフェイスを定義する
doFilter メソッドを定義すると、サブクラスがプロセッサの内部ロジックを実装します。doFilter メソッドの最後のステップでは、忘れずに doNextFilter() を呼び出して doNextFilter メソッドを定義し、抽象クラスによって次のメソッドを呼び出すためのコードが完成することに注意してください
。プロセッサー。
/**
* 处理器抽象类
*
* @author lishuzhen
* @createTime 2022年06月19日 22:52:00
*/
public abstract class AbstractOrderChainHandler {
private AbstractOrderChainHandler nextHandler;
/**
* 执行过滤方法
*
* @param orderDTO
* @return
*/
abstract protected ResultDTO doFilter(OrderDTO orderDTO);
/**
* 执行下一个处理器
*
* @param orderDTO
* @param resultDTO
* @return
*/
protected ResultDTO doNextHandler(OrderDTO orderDTO, ResultDTO resultDTO) {
if (nextHandler == null) {
return resultDTO;
}
return nextHandler.doFilter(orderDTO);
}
public void setNextHandler(AbstractOrderChainHandler nextHandler) {
this.nextHandler = nextHandler;
}
}
3. プロセッサのサブクラス実装を定義する
コンテナの開始時にすべてのプロセッサ実装クラスを取得できるように、抽象プロセッサ インターフェイスを実装する必要があります。
@Order アノテーションは、責任チェーン全体における現在のプロセッサの位置を識別するために使用されます。後でプロセッサを追加するときに便利になるように、間隔を大きく設定することをお勧めします。
/**
* 订单提交-库存计算处理器
*
* @author lishuzhen
* @createTime 2022年06月19日 22:57:00
*/
@Service
@Order(100)
public class StockOrderChainHandler extends AbstractOrderChainHandler {
/**
* 执行过滤方法
*
* @param orderDTO
* @return
*/
@Override
protected ResultDTO doFilter(OrderDTO orderDTO) {
System.out.println("库存计算处理");
return doNextHandler(orderDTO, ResultDTO.ok());
}
}
/**
* 订单提交-价格计算处理器
*
* @author lishuzhen
* @createTime 2022年06月19日 22:59:00
*/
@Service
@Order(300)
public class PriceOrderChainHandler extends AbstractOrderChainHandler {
/**
* 执行过滤方法
*
* @param orderDTO
* @return
*/
@Override
protected ResultDTO doFilter(OrderDTO orderDTO) {
System.out.println("价格计算处理");
return doNextHandler(orderDTO, ResultDTO.ok());
}
}
/**
* 订单提交-优惠券计算处理器
*
* @author lishuzhen
* @createTime 2022年06月19日 22:59:00
*/
@Service
@Order(200)
public class CouponOrderChainHandler extends AbstractOrderChainHandler {
/**
* 执行过滤方法
*
* @param orderDTO
* @return
*/
@Override
protected ResultDTO doFilter(OrderDTO orderDTO) {
System.out.println("优惠券处理");
return doNextHandler(orderDTO, ResultDTO.ok());
}
}
4. カプセル化と結合責任チェーン
@Autowired で責任チェーン (プロセッサのコレクション) を変更することにより、スプリング コンテナは @order の順序で順序付きリストのコレクションを組み立てます。
@PostConstruct を使用して、constructChain() メソッドを変更して、コンテナーがこのメソッドをコールバックして、各プロセスの次のプロセッサーの設定を完了するようにします。firstHandler を定義して、
これが現在の責任リンクの先頭にある最初のプロセッサーであることを示します。
/**
* 订单处理责任链
*
* @author lishuzhen
* @createTime 2022年06月19日 23:05:00
*/
@Service
public class OrderChainHandler {
@Autowired
private List<AbstractOrderChainHandler> chain;
private AbstractOrderChainHandler firstHandler;
@PostConstruct
private void constructChain() {
if (chain == null || chain.size() == 0) {
throw new RuntimeException("not found order chain handler");
}
firstHandler = chain.get(0);
for (int i = 0; i < chain.size(); i++) {
if (i == chain.size() - 1) {
chain.get(i).setNextHandler(null);
} else {
chain.get(i).setNextHandler(chain.get(i + 1));
}
}
}
public ResultDTO executionChain(OrderDTO orderDTO) {
return firstHandler.doFilter(orderDTO);
}
}
5. テストインターフェイスを作成する
@Controller
@RequestMapping("/lsz")
public class OrderTestController {
@Autowired
private OrderChainHandler orderChainHandler;
@ResponseBody
@RequestMapping("testOrder")
public Object testOrder(String orderNo){
return orderChainHandler.executionChain(new OrderDTO()).getMsg();
}
}