spring integration 自启动注册route

下面举一个流程的例子

@Bean  
public IntegrationFlow sample1Definition(IntegrationFlow defaultFlow,  
                                                         IntegrationFlow aFlow,  
                                                         IntegrationFlow bFlow,  
                                                         IntegrationFlow cFlow  
                                                         ) {  
    //业务幂等性判断  
    return IntegrationFlows.from("hotelFulfillmentChannel")  
            .enrichHeaders(h -> h.messageProcessor(payloadAddHeader("path")))  
            .route("headers['path']", m ->  
                    m.subFlowMapping("a", sf-> sf.gateway(aFlow))  
                            .subFlowMapping("b", sf-> sf.gateway(bFlow))  
                            .subFlowMapping("c", sf-> sf.gateway(cFlow))  
                            .defaultSubFlowMapping(sf -> sf.gateway(defaultFlow))  
                            )  
  
            .channel("hotelOutChannel")  
            .get()  
            ;  
}

这是一个简单的流程从hotelFulfillmentChannel 获取数据源,将payload里的字符串放到header里是path, 根据header里path值,路由到a、b、c 路由, 然后路由到aFlow,bFlow,cFlow,3个子流程。最后结果输出到一个hotelOutChannel 管道结束。

每加一个path值,就要先加一个subFlowMapping。在某些情况下,我想不改动flow流程,流程能自己注册到route里,因为我没有完全动态的需要,在写代码的时候其实都已经定下来流程怎么样,只是我想遵守开闭原则,这个流程没有变化就不要动,改变的都集中要一起,防止分散化改动。

所以下面实现一个启动自注册的route

package com.r.travel.flow;  
  
import org.springframework.integration.dsl.IntegrationFlow;  
import org.springframework.integration.dsl.RouterSpec;  
import org.springframework.integration.router.ExpressionEvaluatingRouter;  
import org.springframework.stereotype.Component;  
  
import java.util.Map;  
import java.util.concurrent.ConcurrentHashMap;  
import java.util.function.Consumer;  
  
@Component  
public class FlowRouterSpec {  
    private static final String DEFAULT_FLOW = "default";  
    private final Map<String, IntegrationFlow> fulfillmentTryOrderFlowMappings = new ConcurrentHashMap<>();  
  
    public FlowRouterSpec(IntegrationFlow defaultFlow) {  
        fulfillmentTryOrderFlowMappings.put(DEFAULT_FLOW, defaultFlow);  
  
    }  
    public void registerRoute(String routeKey, IntegrationFlow subFlow) {  
        fulfillmentTryOrderFlowMappings.put(routeKey, subFlow);  
    }  
    // 获取注册的RouterSpec供其他地方使用  
    public Consumer<RouterSpec<String, ExpressionEvaluatingRouter>> getRouterSpec() {  
        return spec -> {  
            fulfillmentTryOrderFlowMappings.forEach((key, flow) ->  
                    spec.subFlowMapping(key, sf -> sf.gateway(flow)));  
  
            // 可选:设置默认路由  
            spec.defaultSubFlowMapping(sf -> sf.gateway(fulfillmentTryOrderFlowMappings.get(DEFAULT_FLOW)));  
        };  
    }  
}

首先实现一个缓存routePath和Integration的map,用于注册上报的缓存。
实现registerRoute方法,用于注册到map中,每个实现类启动调用。
最后getRouterSpec是给主流程的route方法内使用,获取所有routeSpec。
下面是抽象类

public interface FlowFactory {  
    void registerRouter();  
  
    IntegrationFlow getFlow();  
}
package com.r.travel.flow;  
  
import lombok.extern.slf4j.Slf4j;  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.integration.dsl.IntegrationFlow;  
import org.springframework.stereotype.Component;  
  
import javax.annotation.PostConstruct;  
@Slf4j  
@Component  
public class AFlowFactory implements FlowFactory{  
    @Autowired  
    private FlowRouterSpec flowRouterSpec;  
    @PostConstruct  
    public void init(){  
        registerRouter();  
    }  
  
  
    @Override  
    public void registerRouter() {  
        String routerKey = "a";  
        flowRouterSpec.registerRoute(routerKey, getFlow());  
    }  
  
    @Override  
    public IntegrationFlow getFlow() {  
        return f-> f.handle(  
                (p,v)-> {  
                    log.info("dynamic a flow");  
                    return p;  
                }  
        ).logAndReply();  
    }  
  
  
}

某个实现类,使用PostConstruct启动注册,调用FlowRouterSpec的registerRouter方法。

@Bean  
public IntegrationFlow sampleDynamicDefinition(FlowRouterSpec flowRouterSpec) {  
    return IntegrationFlows.from("hotelFulfillmentChannel")  
            .enrichHeaders(h -> h.messageProcessor(payloadAddHeader("path")))  
            .route("headers['path']", flowRouterSpec.getRouterSpec())  
            .channel("hotelOutChannel")  
            .get()  
            ;  
}

最终主流程实现。

参考例子
https://github.com/R-Richie/R-development-lab/tree/main/lefox-travel-example/src/main/java/com/r/travel/controller

https://github.com/R-Richie/R-development-lab/tree/main/lefox-travel-example/src/main/java/com/r/travel/flow

Sample1Flow、FlowRouterSpec、FlowFactory、AFlowFactory、BFlowFactory、CFlowFactory

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值