将 spring 配置映射到集成流程
Mapping spring configuration to integration flows
我有一个 Spring 启动/集成应用程序,其集成流程从 RabbitMQ queues 开始。流程本身和应用程序总体上运行良好,但初始入站 AMQP 配置有很多冗余配置。
目前我有十个 DataType
,每个属性都略有不同,其中一些需要在 运行 时定义。我为每个初始化一个入站流,设置几个headers,然后快速将它们转储到一个公共通道中进行处理。
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
我将映射到 class 或多或少像:
/**
* 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(及其相互关系),并在每个上调用 SingletonBeanRegistry::registerSingleton
.
就是说,我不确定该方法何时应该 运行,以及如何将其变为 运行。一方面,我需要它 运行 一旦配置属性创建的 beans 可以访问,但在生命周期管理开始之前(所以我的集成流将被管理),最好在 RabbitAdmin::afterPropertiesSet
之前我还可以获得我的 RabbitMQ objects 的隐式声明。
我怎样才能做到这一点?
更新:我听从了下面@ArtemBilan 的建议,并能够编写一个模拟示例,我将其包含在此处。
主要 class 的:
@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();
}
}
child 配置:
@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();
}
}
还有一个模型class:
@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 Reference Manual。
我有一个 Spring 启动/集成应用程序,其集成流程从 RabbitMQ queues 开始。流程本身和应用程序总体上运行良好,但初始入站 AMQP 配置有很多冗余配置。
目前我有十个 DataType
,每个属性都略有不同,其中一些需要在 运行 时定义。我为每个初始化一个入站流,设置几个headers,然后快速将它们转储到一个公共通道中进行处理。
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
我将映射到 class 或多或少像:
/**
* 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(及其相互关系),并在每个上调用 SingletonBeanRegistry::registerSingleton
.
就是说,我不确定该方法何时应该 运行,以及如何将其变为 运行。一方面,我需要它 运行 一旦配置属性创建的 beans 可以访问,但在生命周期管理开始之前(所以我的集成流将被管理),最好在 RabbitAdmin::afterPropertiesSet
之前我还可以获得我的 RabbitMQ objects 的隐式声明。
我怎样才能做到这一点?
更新:我听从了下面@ArtemBilan 的建议,并能够编写一个模拟示例,我将其包含在此处。
主要 class 的:
@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();
}
}
child 配置:
@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();
}
}
还有一个模型class:
@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 Reference Manual。