【设计模式】基于spring特性的责任链模式

【设计模式】基于spring特性的责任链模式

业务场景:

业务场景:开发中,需要对返回进行一系列的策略过滤,直接在一个方法中进行,代码比较长,耦合也是比较深。所以用责任链的模式进行解耦,同时可以动态配置责任链,实现动态拔插。

设计:

定义一个过滤链接口:

public interface IFilterChain<ReqT,repD> {
    void doFilter(ReqT req, repD rep);
}

实现接口:这就是一个过滤链的对象

public class LinkedFilterChain implements IFilterChain<RequestContext, RespondContext> ,Cloneable {

    List<IWorkFilter<RequestContext,RespondContext>> filterChain;

    @Override
    public void doFilter(RequestContext req, RespondContext rep) {
        // 循环执行责任链
        for (IWorkFilter<RequestContext, RespondContext> filterChain : filterChain) {
             filterChain.doFilter(req,rep);
        }
    }


    public List<IWorkFilter<RequestContext, RespondContext>> getFilterChains() {
        return filterChain;
    }

    public void setFilterChains(List<IWorkFilter<RequestContext, RespondContext>> filterChains) {
        this.filterChain = filterChains;
    }

    @Override
    protected LinkedFilterChain clone() throws CloneNotSupportedException {
        return (LinkedFilterChain) super.clone();
    }
}

通过doFilter方法执行过滤,这只是一个简单的过滤链,你也可以按照业务需求实现更多的功能,比如:快速失败,等等。。

如何使用

1:定义一个过滤接口:

public interface IWorkFilter<ReqT,RepD> extends Cloneable {
    void doFilter(ReqT req, RepD rep);
}

实现类为过滤节点,这里demo就建立两个过滤节点,通过@Order 实现注入链的顺序

@Component
@Order(1)
@Slf4j
public class FirstLevelWorkFilter implements IWorkFilter<RequestContext,RespondContext> {
    @Override
    public void doFilter(RequestContext req, RespondContext rep) {
        log.info("一级处理器执行。。。");
    }
}
@Component
@Order(2) // 可以通过order对注入责任链的顺序控制
@Slf4j
public class SecondLevelWorkFilter implements IWorkFilter<RequestContext,RespondContext> {
    @Override
    public void doFilter(RequestContext req, RespondContext rep) {
        log.info("执行二级过滤器。。。。");
    }

}

2:建立一个过滤链工厂

  • 可以通过incloudChain 在配置文件中动态注入需要执行的过滤链
  • 通过spring的特性注入所有的过滤链,按照过滤链类名和实现类存入map
  • 提供获取实例的方法,返回过滤链对象
@Component
@Data
@Slf4j
public class FilterFactory {
  private List<IWorkFilter<RequestContext, RespondContext>> filterList;
  private Map<String, IWorkFilter<RequestContext, RespondContext>> filterMap = new HashMap<>();
  private LinkedFilterChain linkedFilterChain;

  //@Value("#{chain}")
  List<String> incloudChain = new ArrayList<>(); // 配置执行链

  // 可以有两种方法注入 1: @Autowired  2:构造器注入
  @Autowired(required = false)
  private List<IWorkFilter<RequestContext, RespondContext>> filters;

  public FilterFactory(List<IWorkFilter<RequestContext, RespondContext>> filters) {
        filterList = filters;
    }

  @PostConstruct
  public void init() {
    // 原始链集合 ,可以基于动态配置,对执行的链接灵活拔插
    for (IWorkFilter filter : filterList) {
      filterMap.put(filter.getClass().getSimpleName(), filter);
    }
    // 获取执行链
    updateChain();
  }

  private void updateChain() {
    LinkedFilterChain realChain = new LinkedFilterChain();
    List<IWorkFilter<RequestContext, RespondContext>> filters = new ArrayList<>();
    realChain.setFilterChains(filters);
    this.linkedFilterChain = realChain;
    if (CollectionUtils.isEmpty(incloudChain)) {
        filters.addAll(filterList);
    }
    for (String filterName : incloudChain) {
      IWorkFilter realFilter = filterMap.get(filterName);
      filters.add(realFilter);
    }

  }

  public LinkedFilterChain getInstance() {
      LinkedFilterChain filterChain = null;
      try{
          filterChain = linkedFilterChain.clone();
      }catch (Exception e){
        log.error("get linkedFilterChain instance got error" ,e);
      }
      return filterChain;
  }
}

测试

测试类

@Autowired
  FilterFactory filterFactory;

 @Test
  void testFilteChain(){
    LinkedFilterChain instance = filterFactory.getInstance();
    RequestContext requestContext = new RequestContext();
    RespondContext respondContext = new RespondContext();
    instance.doFilter(requestContext,respondContext);
  }
2021-03-14 16:43:06.679  INFO 22120 --- [           main] c.l.d.p.d.c.filter.FirstLevelWorkFilter  : 一级处理器执行。。。
2021-03-14 16:43:06.680  INFO 22120 --- [           main] c.l.d.p.d.c.f.SecondLevelWorkFilter      : 执行二级过滤器。。。。

总结:

​ 责任链模式非常适合逻辑比较多的业务,按照每个业务特点拆分成一个个的节点,可以让代码更优雅。这是一个简单demo,实际在使用的时候,可以按照业务需求优化。

That is all~~

posted @ 2021-03-14 16:54  一懒众衫小QAQ  阅读(802)  评论(0编辑  收藏  举报