如何在 spring boot 中实现对一个数据对象的流式处理? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
NLL
2.13D
V2EX    Java

如何在 spring boot 中实现对一个数据对象的流式处理?

  •  
  •   NLL 2022-07-19 15:03:10 +08:00 2975 次点击
    这是一个创建于 1181 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如何在 spring 中实现对同一个数据对象,实现流式处理? 即,定义某一接口,同时定义多个处理类来实现这个接口,在处理数据时,依次(并行)调用这些处理类,在处理类内部,根据业务需求,判断是否需要进行处理,不处理的直接 return 。

    现在的方式是使用策略模式,通过 Autowired 自动注入这些处理类,放入 map ,根据业务类型取出不同的处理类进行处理。

    不知这是否是在 spring boot 中的最佳实现方式? 如果同时需要多个处理类进行处理(如上所述),是否只能在自动注入时放入一个 List 中,进行遍历处理?

    public interface Strategy { Integer getBizCode(); public int doOperation(int num1, int num2); } @Component public class OperationAdd implements Strategy{ @Override public Integer getBizCode() { return 1; } @Override public int doOperation(int num1, int num2) { return num1 + num2; } } @Component public class OperationSubtract implements Strategy{ @Override public Integer getBizCode() { return 2; } @Override public int doOperation(int num1, int num2) { return num1 - num2; } } public class StrategyPatternDemo { HashMap<Integer, Strategy> strategyMap = new HashMap<>(); @Autowired public StrategyPatternDemo(List<Strategy> strategies){ for (Strategy strategy : strategies) { strategyMap.put(strategy.getCode(),strategy); } } public void test(int type, int num1, int num2) { Strategy strategy = strategyMap.get(type); int result = strategy.doOperation(num1, num2); System.out.println(result); } } 
    16 条回复    2022-07-19 19:18:43 +08:00
    yjll9102
        1
    yjll9102  
       2022-07-19 15:12:58 +08:00   1
    看看是否可以使用责任链来处理
    shaneflane
        2
    shaneflane  
       2022-07-19 15:15:49 +08:00   1
    damai0419
        3
    damai0419  
       2022-07-19 15:19:01 +08:00   1
    感觉也是责任链模式,听起来比较符合。
    NLL
        4
    NLL  
    OP
       2022-07-19 15:29:03 +08:00
    @yjll9102 #1
    @damai0419 #3
    感谢,好像对于依次调用的场景是可以的,那如果对于没有前后逻辑的,可以并行处理的场景,是否有其他的方式呢?
    damai0419
        5
    damai0419  
       2022-07-19 15:36:24 +08:00
    @zhijiansha
    包装一下逻辑,内部用异步多线程处理?
    或者直接用 CompletableFuture 处理?
    zmal
        6
    zmal  
       2022-07-19 15:52:03 +08:00
    数据结构可以选择一个支持并发的队列。

    你可以说一下具体的场景,感觉像是一个 A-B 问题。
    vvtf
        7
    vvtf  
       2022-07-19 16:21:04 +08:00   1
    ```java

    interface Rule<T extends S> {

    T run(T... args);

    default boolean enabled() {
    return true;
    }

    default boolean async() {
    return false;
    }

    }

    @Order(0)
    @Component
    class RuleA implements Rule<SomeA> {

    T run(T... args) {
    // TODO
    }

    boolean async() {return true;}

    }

    @Component
    class RuleChain {
    @Autowired
    private List<Rule> rules;

    static ExecutorService pool = xxxx;

    public void run(T... args) {

    rules.stream().filter(Rule::enabled).filter(Rule::async).forEach(rule -> pool.execute(rule.run()););
    rules.stream().filter(Rule::enabled).filter(rule -> !rule.async()).forEach(Rule::run);

    }

    }

    ```
    NLL
        8
    NLL  
    OP
       2022-07-19 16:24:44 +08:00
    @damai0419 #5
    @zmal #6
    抱歉,可能我的描述有些问题,我现在面临的场景,是没有先后逻辑的,可以乱序执行,而责任链模式,好像是必须要指定 next ?比如有 A 、B 、C 三个处理类,需要执行情况 可能是 AB 、AC 、ABC 这种,我现在能想到的就是把这些处理类都放进一个 list 中,通过 for 循环,传入复制的数据对象进行处理
    NLL
        9
    NLL  
    OP
       2022-07-19 16:29:52 +08:00
    @vvtf #7 感谢感谢
    zmal
        10
    zmal  
       2022-07-19 16:33:56 +08:00
    如果你的执行函数可以不区分前后,那还叫流式处理吗?
    真实场景到底是什么?建议讲清楚。
    genesys
        11
    genesys  
       2022-07-19 16:38:31 +08:00 via iPhone
    “ 依次(并行)调用这些处理类” 到底是依次还是并行,差别很大的。
    如果是并行的话,首先要选择如何实现并行。具体并行下执行的 task ,也许你可以考虑策略模式之类的。
    NLL
        12
    NLL  
    OP
       2022-07-19 17:07:55 +08:00
    @zmal #10
    @genesys #11
    抱歉,标题和内容可能表述有误,我想请教 依次调用、并行调用这两种情况下的最佳实现方式。
    #1 、#3 提到的责任链能解决依次调用
    #7 提供的代码 demo 可以解决 并行调度
    感谢
    genesys
        13
    genesys  
       2022-07-19 18:33:17 +08:00 via iPhone   1
    @zhijiansha 没关系。多提问挺好,这也是对自己提问能力的锻炼,提问能力是工作中很重要的一项技能。
    kytrun
        14
    kytrun  
       2022-07-19 18:35:09 +08:00   1
    如果不需要拿到每一步的结果,直接 @ Async 完事儿
    0xLittleFi
        15
    0xLittleFi  
       2022-07-19 19:07:53 +08:00   1
    可以搜下开源的 easyflow 是咋实现的
    zhangleshiye
        16
    zhangleshiye  
       2022-07-19 19:18:43 +08:00
    @zhijiansha 根据 8 楼的信息 , 我感觉楼主是不是想要响应式编程的那种链式编程?类似
    rxjava observable.zip<A,B,C>(getDataA(),getDataB) .(new subscribtion(A a,B ,b){
    return ConvertC(a,b)
    })
    这样?
    好久没用 rxjava 了 , 大概意思是这样..
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2750 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 12:15 PVG 20:15 LAX 05:15 JFK 08:15
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86