簡體   English   中英

將 spring 配置映射到集成流

[英]Mapping spring configuration to integration flows

我有一個 Spring Boot / Integration 應用程序,它的集成流程從 RabbitMQ 隊列開始。 流本身和應用程序總體上運行良好,但初始入站 AMQP 配置有很多冗余配置。

目前我有十個DataType ,每個都有略微不同的屬性,其中一些需要在運行時定義。 我為每個流初始化一個入站流,設置幾個標頭,然后快速將它們轉儲到公共通道中進行處理。

NetworkDiagnostic DataType之一的 Java 配置如下所示:

@Bean
public IntegrationFlow inboundNetworkDiagnosticFlow(@Qualifier("connectionFactory") ConnectionFactory connectionFactory,
                                                    @Qualifier(BeanNames.INBOUND_EVENTS_CHANNEL) MessageChannel outbound,
                                                    @Qualifier(BeanNames.JSON_NODE_MESSAGE_CONVERTER) MessageConverter messageConverter,
                                                    @Qualifier("networkDiagnosticQueue") Queue queue,
                                                    @Value("${networkDiagnostic.numConsumers}") int numConsumers,
                                                    @Value("${networkDiagnostic.prefetchCount}") int prefetchCount) {
    return makeEventIntegrationFlow(connectionFactory, outbound, messageConverter, queue, numConsumers, prefetchCount,
            DataTypes.EVENT_NETWORK_DIAGNOSTIC);

}

@Bean
public Binding networkDiagnosticBinding(@Qualifier("networkDiagnosticQueue") Queue queue) {
    return makeFanoutBinding(queue, NETWORK_DIAGNOSTIC_EXCHANGE_NAME);
}


@Bean
public Queue networkDiagnosticQueue() {
    return makeQueue(NETWORK_DIAGNOSTIC_QUEUE_STRING);
}

@Bean
public FanoutExchange networkDiagnosticExchange() {
    return new FanoutExchange(NETWORK_DIAGNOSTIC_EXCHANGE_NAME);
}

另外九個有並聯配置。 我想更多地考慮這一點,以便 a) 刪除重復,並且 b) 只需從服務器上的配置文件即可配置更多輸入。

我的一般想法是我會有一個 yaml 配置文件:

data_types:
   - name: network-diagnostic
     schema: event
     window_type: hourly
     exchange_name: blahblahblah
     queue_name: blahblahblah
     ...
   - name: log-diagnostic
   ...

其中,通過@ConfigurationProperties我或多或少地映射到一個類:

 /**
 * Organizes information and configuration for a DataType
 */
public class DataType {
    private String name;
    private Schema schema;
    private WindowType windowType;
    private long bucketLength;

    private String exchange;
    private String routingKey;
    ...

而且我需要一些方法—— registerAllBeans期待所有的數據類型,它創建所有必要的 bean(及其相互關系),並在每個 bean 上調用SingletonBeanRegistry::registerSingleton

也就是說,我不確定該方法應該何時運行,以及如何讓它運行。 一方面,一旦配置屬性創建的 bean 可訪問,我需要它運行,但在生命周期管理開始之前(因此我的集成流將被管理),並且最好在RabbitAdmin::afterPropertiesSet之前RabbitAdmin::afterPropertiesSet這樣我也可以獲得我的 RabbitMQ 對象的隱式聲明。

我怎樣才能做到這一點?

更新:我從下面遵循@ArtemBilan 的建議,並能夠編寫一個模擬示例,我將其包括在此處。

一個主要類別:

@EnableAutoConfiguration
@Configuration
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplicationBuilder parentBuilder = new SpringApplicationBuilder(DemoApplication.class);
        parentBuilder.child(ChildConfiguration.class).properties("name=bob", "message='hi how are you?'").run();
        parentBuilder.child(ChildConfiguration.class).properties("name=jane", "message='hi how are you?'").run();
    }

    @Bean
    public IntegrationFlow integrationFlow() {
        Object object = new Object();
        return IntegrationFlows.from("inputChannel")
                .handle(m -> System.out.println(object + " " + m.getPayload() + " " + System.currentTimeMillis()))
                .get();
    }
}

一個子配置:

@EnableAutoConfiguration
@EnableConfigurationProperties(Sample.class)
@Configuration
public class ChildConfiguration {

    @Bean
    public IntegrationFlow anotherOutgoingFlow(Sample sample) {
        return IntegrationFlows
                .from(() -> new GenericMessage<>("hello " + sample.getName() + "; " + sample.getMessage()),
                        m -> m.poller(Pollers.fixedDelay(500)))
                .channel("inputChannel")
                .get();
    }
}

和一個模型類:

@ConfigurationProperties
public class Sample {
    private String name;
    private String message;

    public Sample() { }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

打印,例如:

2016-03-25 17:12:04.109  INFO 24637 --- [           main] com.example.DemoApplication              : Started DemoApplication in 0.169 seconds (JVM running for 3.878)
java.lang.Object@25c4da11 hello bob; 'hi how are you?' 1458940324438
java.lang.Object@25c4da11 hello jane; 'hi how are you?' 1458940324607
java.lang.Object@25c4da11 hello bob; 'hi how are you?' 1458940324938
java.lang.Object@25c4da11 hello jane; 'hi how are you?' 1458940325108
java.lang.Object@25c4da11 hello bob; 'hi how are you?' 1458940325439

考慮為您的應用程序使用parent/child架構,屆時您將能夠根據提供的環境重用模板配置。

有關更多信息,請參閱Spring Boot 參考手冊

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM