SI 的基本接口和编程方法(官方文档摘录)转

SI 的基本接口和编程方法(官方文档摘录)

消息

消息结构

public interface Message<T> {
	T getPayload();
    MessageHeaders getHeaders();
}

消息头

public final class MessageHeaders implements Map<String, Object>, Serializable {
  // ...
}

从消息头读取属性

Object someValue = message.getHeaders().get("someKey");
CustomerId customerId = message.getHeaders().get("customerId", CustomerId.class);
Long timestamp = message.getHeaders().getTimestamp();

只读消息头

包装成消息的几种方式

  • 直接 new
new GenericMessage<T>(T payload);
new GenericMessage<T>(T payload, Map<String, Object> headers)
  • 打包成消息
Message<String> message1 = MessageBuilder.withPayload("Hello World!")
        .setHeader("foo", "bar")
        .build();
  • 复制消息
Message<String> message2 = MessageBuilder.fromMessage(message1).build();
  • 打包负载 + 复制消息头
Message<String> message3 = MessageBuilder.withPayload("One More Thing!")
        .copyHeaders(message1.getHeaders())
        .build();
  • 设置优先级
Message<Integer> importantMessage = MessageBuilder.withPayload("Hello Tiger!")
        .setPriority(5)
        .build();

消息通道

最基础的消息通道接口

public interface MessageChannel {
    boolean send(Message message);
    boolean send(Message message, long timeout);
}

轮询通道

public interface PollableChannel extends MessageChannel {
    Message<?> receive();
    Message<?> receive(long timeout);
}

订阅通道

public interface SubscribableChannel extends MessageChannel {
    boolean subscribe(MessageHandler handler);
    boolean unsubscribe(MessageHandler handler);
}

连接两个通道

@BridgeFrom

@Bean
public PollableChannel polled() {
    return new QueueChannel();
}

@Bean
@BridgeFrom(value = "polled", poller = @Poller(fixedDelay = "5000", maxMessagesPerPoll = "10"))
public SubscribableChannel direct() {
    return new DirectChannel();
}

@BridgeTo

@Bean
@BridgeTo(value = "direct", poller = @Poller(fixedDelay = "5000", maxMessagesPerPoll = "10"))
public PollableChannel polled() {
    return new QueueChannel();
}

@Bean
public SubscribableChannel direct() {
    return new DirectChannel();
}

BridgeHandler

@Bean
@ServiceActivator(inputChannel = "polled",
        poller = @Poller(fixedRate = "5000", maxMessagesPerPoll = "10"))
public BridgeHandler bridge() {
    BridgeHandler bridge = new BridgeHandler();
    bridge.setOutputChannelName("direct");
    return bridge;
}

JavaDSL

@Bean
public IntegrationFlow bridgeFlow() {
    return IntegrationFlows.from("polled")
            .bridge(e -> e.poller(Pollers.fixedDelay(5000).maxMessagesPerPoll(10)))
            .channel("direct")
            .get();
}

连接消息源

两种消费者,对应两种通道

  • EventDrivenConsumer 从 SubscribableChannel 订阅消息
  • PollingConsumer 从 PollableChannel 轮询消息

接入消息系统

  • MessageProducerSupport
  • MessageSource (通过 SourcePollingChannelAdapter 连接 MessageChannel)

范例:订阅数据源

@Bean
public MessageProducerSupport redisInboundChannelAdapter(RedisConnectionFactory redisConnectionFactory) {
    RedisInboundChannelAdapter adapter = new RedisInboundChannelAdapter(redisConnectionFactory);
    adapter.setTopics("foo");
    return adapter;
}

范例:从消息源轮询数据

@Bean
@InboundChannelAdapter(value = "fooChannel", poller = @Poller(fixedDelay="5000"))
public MessageSource<?> storedProc(DataSource dataSource) {
    return new JdbcPollingChannelAdapter(dataSource, "SELECT * FROM foo where status = 0");
}

router

基本的写法:用 JavaDSL 串流程,用 handle() 引用 router 定义方法

@Bean
public IntegrationFlow routerFlow() {
    return IntegrationFlows.from("routingChannel")
            .route(myCustomRouter())
            .get();
}

自定义 router

public AbstractMessageRouter myCustomRouter() {
    return new AbstractMessageRouter() {
        @Override
        protected Collection<MessageChannel> determineTargetChannels(Message<?> message) {
            return // determine channel(s) for message
        }
    };
}

函数式写法

@Bean
public IntegrationFlow routerFlow() {
    return IntegrationFlows.from("routingChannel")
            .route(String.class, p -> p.contains("foo") ? "fooChannel" : "barChannel")
            .get();
}

常用的几种 router

负载类型 router

public PayloadTypeRouter router() {
    PayloadTypeRouter router = new PayloadTypeRouter();
    router.setChannelMapping(String.class.getName(), "stringChannel");
    router.setChannelMapping(Integer.class.getName(), "integerChannel");
    return router;
}

头属性 router

public HeaderValueRouter router() {
    HeaderValueRouter router = new HeaderValueRouter("testHeader");
    router.setChannelMapping("someHeaderValue", "channelA");
    router.setChannelMapping("someOtherHeaderValue", "channelB");
    return router;
}

表达式 router

public ExpressionEvaluatingRouter router() {
    ExpressionEvaluatingRouter router = new ExpressionEvaluatingRouter("payload.paymentType");
    router.setChannelMapping("CASH", "cashPaymentChannel");
    router.setChannelMapping("CREDIT", "authorizePaymentChannel");
    router.setChannelMapping("DEBIT", "authorizePaymentChannel");
    return router;
}

函数式写法的表达式 router

@Bean
public IntegrationFlow routerFlow() {
    return IntegrationFlows.from("routingChannel")
        .route("payload.paymentType", r -> r
            .channelMapping("CASH", "cashPaymentChannel")
            .channelMapping("CREDIT", "authorizePaymentChannel")
            .channelMapping("DEBIT", "authorizePaymentChannel"))
        .get();
}

Filter

MessageSelector

public interface MessageSelector {
    boolean accept(Message<?> message);
}

使用 MessageSelector 构造 MessageFilter

MessageFilter filter = new MessageFilter(someSelector);

用注解定义一个过滤器

public class PetFilter {
    ...
    @Filter  
    public boolean dogsOnly(String input) {
        ...
    }
}

Splitter

用注解定义一个 Splitter

@Splitter
List<LineItem> extractItems(Order order) {
    return order.getItems()
}

Handler

public interface MessageHandler {
    void handleMessage(Message<?> message);
}

MessageGateway

@MessagingGateway

范例:三个入口方法的 Gateway

@MessagingGateway(defaultRequestChannel = "inputC", defaultHeaders = @GatewayHeader(name = "calledMethod", expression="#gatewayMethod.name"))
public interface TestGateway {

   @Gateway(requestChannel = "inputA", replyTimeout = 2, requestTimeout = 200)
   String echo(String payload);
   
   @Gateway(requestChannel = "inputB", headers = @GatewayHeader(name = "thing1", value="thing2"))
   String echoUpperCase(String payload);
   
   String echoViaDefault(String payload);
}

JavaDSL

IntegrationFlows

  • transform → Transformer
  • filter → Filter
  • handle → ServiceActivator
  • split → Splitter
  • aggregate → Aggregator
  • route → Router
  • bridge → Bridge

从 Channel 开始流程

@Bean
public IntegrationFlow testFlow1() {
    return IntegrationFlows.from("some-channel")
            .handle(m -> System.out.println(m)).get();
}

从 Gateway 开始流程

@Bean
public IntegrationFlow testFlow2() {
    return IntegrationFlows.from("some-gateway.input")
            .handle(m -> System.out.println(m)).get();
}

定义子流程

@Bean
public IntegrationFlow routeFlow() {
    return f -> f
            .<Integer, Boolean>route(p -> p % 2 == 0,
                    m -> m.channelMapping("true", "evenChannel")
                            .subFlowMapping("false", sf ->
                                    sf.<Integer>handle((p, h) -> p * 3)))
            .transform(Object::toString)
            .channel(c -> c.queue("oddChannel"));
}

开发中的问题

  • 怎么看文档 ref & javadoc
  • 怎么看范例 xml & annotation & javadsl
spring-integration-samples-master
	basic
	applications
	dsl
  • 怎么创建项目

    1. 创建 Spring Boot 项目
    2. 添加 @EnableIntegration,启用 si 支持
    3. 如有必要,添加 @IntegrationComponentScan 或者 @ComponentScan 指定扫描路径
  • 风格套路

    1. 用 Gateway 以 API 方式提供消息系统入口
    2. JavaDSL 和 Annotation 结合
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值