java:责任链设计模式配合Spring@Order注解使用场景

时间:2023-01-13 08:53:47

java:责任链设计模式配合Spring@Order注解使用场景

1 前言

java的责任链模式,经典使用的场景为SpringMVC的doDispatch下,针对请求的过滤链式行为。实际开发场景中,可配合Spring的@Order注解,定义1个有顺序的链式Components列表,根据Components列表的顺序依次处理,如果中途存在处理失败的Component,则终止(或过滤,依赖实际场景即可)整个处理过程,实际使用方式见如下。

2 使用

链式调用的client接口:

public interface IHandleChain {

    boolean handleChain();
}

链式调用的client抽象类:

package com.xiaoxu.handleChain;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import java.util.List;

/**
 * @author xiaoxu
 * @date 2023-01-09
 * java_demo2:com.xiaoxu.handleChain.AbstractHandleChain
 */
public abstract class AbstractHandleChain implements IHandleChain{
    @Autowired
    List<IHandle> handlers;

    IHandle handler;

    @PostConstruct
    public void postHandlers(){
        if(CollectionUtils.isEmpty(handlers)){
            throw new RuntimeException("handlers should not be null or empty.");
        }
        System.out.println("开始执行postHandlers...");
        IHandle currentHandler;
        IHandle nextHandler;
        for (int i = 0; i < handlers.size(); i++) {
            if(i == 0){
                handler = handlers.get(0);
            }else{
                currentHandler = handlers.get(i-1);
                nextHandler = handlers.get(i);
                currentHandler.setNextIHandle(nextHandler);
            }
        }
        System.out.println("handleChain:"+handler);
    }

    protected boolean handle(){
        if(null == this.handler){
            throw new RuntimeException("handler should not be null.");
        }
        return this.handler.handle();
    }

}

上述抽象类获取的链式client处理对象:

java:责任链设计模式配合Spring@Order注解使用场景

链式调用Client:

package com.xiaoxu.handleChain;

import org.springframework.stereotype.Component;

/**
 * @author xiaoxu
 * @date 2023-01-09
 * java_demo2:com.xiaoxu.handleChain.HandleChainClient
 */
@Component
public class HandleChainClient extends AbstractHandleChain{

    @Override
    public boolean handleChain() {
        boolean res;
        if(res = this.handle()){
            System.out.println("全部业务处理成功!");
        }else{
            System.out.println("事务中途处理失败!!!");
        }
        return res;
    }

}

IHandle接口:

public interface IHandle {

    void setNextIHandle(IHandle iHandle);

    IHandle getNextIHandle();

    boolean doHandle();

    boolean handle();
}

IHandle抽象类:

package com.xiaoxu.handleChain;

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

/**
 * @author xiaoxu
 * @date 2023-01-10
 * java_demo2:com.xiaoxu.handleChain.AbstractIHandle
 */
public abstract class AbstractIHandle implements IHandle{

    IHandle nextIHandle;

    @Override
    public void setNextIHandle(IHandle iHandle) {
        this.nextIHandle = iHandle;
    }

    @Override
    public IHandle getNextIHandle() {
        return this.nextIHandle;
    }

    @Override
    public boolean handle() {
        boolean res = this.doHandle();
        if(res){
            if(null != getNextIHandle()){
                return getNextIHandle().handle();
            }
            return true;
        }
        return false;
    }

    @Override
    public String toString(){
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }
}

IHandle的具体处理实现类:

链式处理step1:前置检查

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * @author xiaoxu
 * @date 2023-01-09
 * java_demo2:com.xiaoxu.handleChain.PreHandle
 */
@Component
@Order(value = 1)
public class PreHandle extends AbstractIHandle{

    @Override
    public boolean doHandle() {
        System.out.println("前置检查...");
        return true;
    }

}

链式处理step2:安全检查

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * @author xiaoxu
 * @date 2023-01-09
 * java_demo2:com.xiaoxu.handleChain.CheckSecurityHandle
 */
@Component
@Order(value = 2)
public class CheckSecurityHandle extends AbstractIHandle{

    @Override
    public boolean doHandle() {
        System.out.println("安全检查...");
        return true;
    }

}

链式处理step3:业务处理

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * @author xiaoxu
 * @date 2023-01-09
 * java_demo2:com.xiaoxu.handleChain.ServiceHandle
 */
@Component
@Order(value = 3)
public class ServiceHandle extends AbstractIHandle{

    @Override
    public boolean doHandle() {
        System.out.println("业务处理...");
        return true;
    }

}

链式处理step4:后置处理

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * @author xiaoxu
 * @date 2023-01-09
 * java_demo2:com.xiaoxu.handleChain.PostHandle
 */
@Component
@Order(value = 4)
public class PostHandle extends AbstractIHandle{

    @Override
    public boolean doHandle() {
        System.out.println("后置处理...");
        return true;
    }

}

编写单测执行:

import com.xiaoxu.MainApplication;
import com.xiaoxu.handleChain.HandleChainClient;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

/**
 * @author xiaoxu
 * @date 2023-01-09
 * java_demo2:PACKAGE_NAME.TestHandle
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MainApplication.class)
public class TestHandle {
    @Autowired
    HandleChainClient client;

    @Test
    public void test_01(){
        boolean b = client.handleChain();
        System.out.println("结果为:" + b);
    }

}

执行结果如下,可见达到了链式处理的效果:

java:责任链设计模式配合Spring@Order注解使用场景

若将业务处理的返回改为false后再次执行:

java:责任链设计模式配合Spring@Order注解使用场景

结果如下所示:

java:责任链设计模式配合Spring@Order注解使用场景