我想知道在初始化许多RabbitMQ队列/绑定时,是否有一种方法可以减少SpringBoot中样板代码的数量?
按照事件驱动的方法,我的应用程序产生了大约50种类型的事件(稍后会分成几个较小的应用程序,但仍然如此)。每个事件都以“主题”类型进行交换。有些事件正在被其他应用程序所消耗,有些事件则是由发送它们的同一个应用程序额外消耗的。
让我们考虑一下出版和自我消费的情况。
在SpringBoot for 中,我需要声明每个事件:
SO-6以一种或另一种形式提及“购买物品”的场所。如果有50个事件,很容易出错--当添加新事件时,您需要记住将它添加到6个位置。
理想情况下,对于每一项活动,我想:
有没有优化它的方法?我考虑了自定义注释,但是RabbitListener不喜欢动态队列名,如果我在某些util方法中声明队列和绑定,那么spring引导就找不到bean。也许有一种方法可以在代码中声明所有这些东西,但我相信这不是Spring的方法:)
发布于 2019-02-15 13:16:07
因此,我最终使用了手动bean声明,并对每个bean使用了一个bind()方法
@Configuration
@EnableConfigurationProperties(RabbitProperties::class)
class RabbitConfiguration(
private val properties: RabbitProperties,
private val connectionFactory: ConnectionFactory
) {
@Bean
fun admin() = RabbitAdmin(connectionFactory)
@Bean
fun exchange() = TopicExchange(properties.template.exchange)
@Bean
fun rabbitMessageConverter() = Jackson2JsonMessageConverter(
jacksonObjectMapper()
.registerModule(JavaTimeModule())
.registerModule(Jdk8Module())
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)
)
@Value("\${okko.rabbit.queue-prefix}")
lateinit var queuePrefix: String
fun <T> bind(routingKey: String, listener: (T) -> Mono<Void>): SimpleMessageListenerContainer {
val queueName = "$queuePrefix.$routingKey"
val queue = Queue(queueName)
admin().declareQueue(queue)
admin().declareBinding(BindingBuilder.bind(queue).to(exchange()).with(routingKey)!!)
val container = SimpleMessageListenerContainer(connectionFactory)
container.addQueueNames(queueName)
container.setMessageListener(MessageListenerAdapter(MessageHandler(listener), rabbitMessageConverter()))
return container
}
internal class MessageHandler<T>(private val listener: (T) -> Mono<Void>) {
// NOTE: don't change name of this method, rabbit needs it
fun handleMessage(message: T) {
listener.invoke(message).subscribeOn(Schedulers.elastic()).subscribe()
}
}
}
@Service
@Configuration
class EventConsumerRabbit(
private val config: RabbitConfiguration,
private val routingKeys: RabbitEventRoutingKeyConfig
) {
@Bean
fun event1() = handle(routingKeys.event1)
@Bean
fun event2() = handle(routingKeys.event2)
...
private fun<T> handle(routingKey: String): Mono<Void> = config.bind<T>(routingKey) {
log.debug("consume rabbit event: $it")
... // handle event, return Mono<Void>
}
companion object {
private val log by logger()
}
}
@Configuration
@ConfigurationProperties("my.rabbit.routing-key.event")
class RabbitEventRoutingKeyConfig {
lateinit var event1: String
lateinit var event2: String
...
}https://stackoverflow.com/questions/54634670
复制相似问题