spring版責(zé)任鏈模式

責(zé)任鏈模式顧名思義就是。執(zhí)行一串業(yè)務(wù)處理,像鏈子一樣,從上向下,一個(gè)節(jié)點(diǎn)一個(gè)節(jié)點(diǎn)有序執(zhí)行,中間任何一個(gè)節(jié)點(diǎn)掛啦,鏈子就斷了,不會(huì)繼續(xù)向下執(zhí)行

實(shí)現(xiàn)思路就是把一個(gè)個(gè)處理器類放到一個(gè)數(shù)組list中,遍歷數(shù)組,從第一個(gè)到末尾一個(gè)個(gè)執(zhí)行 handle 方法,數(shù)組list就是一個(gè)鏈子,一個(gè)個(gè)對(duì)象的處理方法就是責(zé)任,合起來(lái)就是責(zé)任鏈咯!

import org.springframework.lang.Nullable;

/**
 * 描述: 業(yè)務(wù)處理頂級(jí)攔截器接口 </br>
 * 時(shí)間: 2021-03-02 14:46  </br>
 * 作者:IT學(xué)習(xí)道場(chǎng)
 */
public interface HandleIntercept {
    /**
     * 業(yè)務(wù)頂級(jí)接口處理接口
     * @param model 泛型參數(shù)
     * @return 成功的對(duì)象返回,可以是boolean,string,model
     */
    Object handle(@Nullable Object model);
}
第一個(gè)業(yè)務(wù)處理攔截器
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * 描述: 第一個(gè)業(yè)務(wù)處理攔截器 </br>
 * 時(shí)間: 2021-03-02 14:57  </br>
 * 作者:IT學(xué)習(xí)道場(chǎng)
 */
@Order(2)
@Component
public class FirstHandleIntercept implements HandleIntercept {

    @Override
    public Object handle(Object model) {
        System.out.println("========執(zhí)行 firstHandleIntercept 開始業(yè)務(wù)處理 =======");
        return true;
    }
}
第二業(yè)務(wù)處理器
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * 描述: 第二業(yè)務(wù)處理器 </br>
 * 時(shí)間: 2021-03-02 15:02  </br>
 * 作者:IT學(xué)習(xí)道場(chǎng)
 */
@Order(1)
@Component
public class SecondHandleIntercept implements HandleIntercept {
    @Override
    public Object handle(Object model) {
        System.out.println("========執(zhí)行 SecondHandleIntercept =======");
        return true;
    }

}
第三業(yè)務(wù)處理器
import org.springframework.stereotype.Component;

/**
 * 描述: 第二業(yè)務(wù)處理器 </br>
 * 時(shí)間: 2021-03-02 15:02  </br>
 * 作者:IT學(xué)習(xí)道場(chǎng)
 */
//@Order(1)
@Component
public class ThirdHandleIntercept implements HandleIntercept {
    @Override
    public Object handle(Object model) {
        System.out.println("========執(zhí)行 ThirdHandleIntercept =======");
        return true;
    }

}
業(yè)務(wù)處理器門面入口






import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 描述: 業(yè)務(wù)處理器門面入口 </br>
 * 時(shí)間: 2021-03-02 15:05  </br>
 * 作者:IT學(xué)習(xí)道場(chǎng)
 */
@Component
public class HandleInterceptEntrance {

    @Autowired
    private Map<String, HandleIntercept> HandleInterceptBeanMap = new ConcurrentHashMap<>();
    //業(yè)務(wù)鏈?zhǔn)教幚砥鱨ist
    private static List<HandleIntercept> HandleInterceptList = new ArrayList<>();

    /**
     * 鏈?zhǔn)教幚砣肟?,類似門面
     */
    public void handleEntrance() {
        if (CollectionUtils.isEmpty(HandleInterceptList)){
            getHandleInterceptList ();
        }
        for (HandleIntercept handleIntercept : HandleInterceptList) {
            //要注入?yún)?shù),可以在此處理
            handleIntercept.handle(null);
        }

    }

    /**
     * 處理攔截器拍尋,解決order排序不生效問(wèn)題
     * 并把HandleIntercept注入到HandleInterceptList中
     */
    @PostConstruct
    private synchronized void getHandleInterceptList () {
        //存貯不帶order注解的攔截器容器list
        List<HandleIntercept> noOrderHandleInterceptList = new ArrayList<>();
        //存貯帶order注解的攔截器容器list
        List<HandleIntercept> orderHandleInterceptList = new ArrayList<>();
        //處理HandleIntercept的springioc容器中的HandleIntercept,處理到
        //noOrderHandleInterceptList和orderHandleInterceptList
        for (String beanName : HandleInterceptBeanMap.keySet()) {
            HandleIntercept handleIntercept = HandleInterceptBeanMap.get(beanName);
            //獲取order注解
            Order order = handleIntercept.getClass().getAnnotation(Order.class);
            if (ObjectUtils.isEmpty(order)){
                noOrderHandleInterceptList.add(handleIntercept);
            }else {
                orderHandleInterceptList.add(handleIntercept);
            }
        }
        //對(duì)orderHandleInterceptList進(jìn)行oder注解的value值升序排列
        if (!CollectionUtils.isEmpty(orderHandleInterceptList)){
            Collections.sort(orderHandleInterceptList, new Comparator<HandleIntercept>() {
                @Override
                public int compare(HandleIntercept h1, HandleIntercept h2) {
                    //升序
                    Integer value1 = h1.getClass().getAnnotation(Order.class).value();
                    Integer value2 = h2.getClass().getAnnotation(Order.class).value();
                    return value1.compareTo(value2);
                }
            });
        }
        //優(yōu)先orderHandleInterceptList注入HandleInterceptList
        HandleInterceptList.addAll(orderHandleInterceptList);
        HandleInterceptList.addAll(noOrderHandleInterceptList);
    }

}
使用示例demo

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@Slf4j
@RestController
@RequestMapping("/test")
public class HandleController {

    @Autowired
    private HandleInterceptEntrance handleEntrance;

    @GetMapping("/handleEntrance")
    public void test() {
        handleEntrance.handleEntrance();
    }


}
責(zé)任鏈模式顧名思義就是。執(zhí)行一串業(yè)務(wù)處理,像鏈子一樣,從上向下,一個(gè)節(jié)點(diǎn)一個(gè)節(jié)點(diǎn)有序執(zhí)行,中間任何一個(gè)節(jié)點(diǎn)掛啦,鏈子就斷了,不會(huì)繼續(xù)向下執(zhí)行

實(shí)現(xiàn)思路就是把一個(gè)個(gè)處理器類放到一個(gè)數(shù)組list中,遍歷數(shù)組,從第一個(gè)到末尾一個(gè)個(gè)執(zhí)行 handle 方法,數(shù)組list就是一個(gè)鏈子,一個(gè)個(gè)對(duì)象的處理方法就是責(zé)任,合起來(lái)就是責(zé)任鏈咯!

其實(shí)這里面包含了,工廠模式,單例模式。門面模式和責(zé)任鏈綜合使用,很多情況都是多種模式配合使用

看明白后,要自己動(dòng)手玩玩吧,自己寫,不要抄,實(shí)在搞不定,再看看,不要copy,使用場(chǎng)景需要一連串的不同的業(yè)務(wù)處理的操作場(chǎng)景,可以考慮責(zé)任鏈,經(jīng)典場(chǎng)景:ip很名單處理 ->登錄處理 -> 權(quán)限處理等類似不同處理維度的連續(xù)不間斷處理,考慮責(zé)任鏈






作者:IT學(xué)習(xí)道場(chǎng)

歡迎關(guān)注微信公眾號(hào) : IT學(xué)習(xí)道場(chǎng)