问题描述
我将 Spring Integration 4.3.11 与 Spring Data MongoDB 1.10.6 一起使用.我有一个使用 MongoDbMessageStore
的消息聚合器.当来自消息序列的消息传入时,它会保留在 MongoDB 中,但紧接着(在 osistore.AbstractMessageGroupStore#addMessageToGroup
中)当从 MongoDB 读取相同消息时抛出异常>
I'm using Spring Integration 4.3.11 with Spring Data MongoDB 1.10.6. I have a message aggregator that uses MongoDbMessageStore
. When a message from a message sequence comes in, it's persisted in MongoDB, but immediately after that (in o.s.i.store.AbstractMessageGroupStore#addMessageToGroup
) an exception is thrown when the same message is read from MongoDB that
Failed to instantiate [org.springframework.messaging.support.GenericMessage]: No default constructor found
完整的堆栈跟踪:
org.springframework.messaging.MessageHandlingException: error occurred in message handler [org.springframework.integration.dsl.AggregatorSpec$InternalAggregatingMessageHandler#0]; nested exception is org.springframework.data.mapping.model.MappingInstantiationException: Failed to instantiate org.springframework.messaging.support.GenericMessage using constructor NO_CONSTRUCTOR with arguments
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:139)
at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:116)
at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:148)
at org.springframework.integration.dispatcher.UnicastingDispatcher.access$000(UnicastingDispatcher.java:53)
at org.springframework.integration.dispatcher.UnicastingDispatcher$3.run(UnicastingDispatcher.java:129)
at org.springframework.integration.util.ErrorHandlingTaskExecutor$1.run(ErrorHandlingTaskExecutor.java:55)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.data.mapping.model.MappingInstantiationException: Failed to instantiate org.springframework.messaging.support.GenericMessage using constructor NO_CONSTRUCTOR with arguments
at org.springframework.data.convert.ReflectionEntityInstantiator.createInstance(ReflectionEntityInstantiator.java:64)
at org.springframework.data.convert.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:83)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:259)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:239)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:199)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:195)
at org.springframework.integration.mongodb.store.MongoDbMessageStore$MessageReadingMongoConverter.read(MongoDbMessageStore.java:520)
at org.springframework.integration.mongodb.store.MongoDbMessageStore$MessageReadingMongoConverter.read(MongoDbMessageStore.java:529)
at org.springframework.integration.mongodb.store.MongoDbMessageStore$MessageReadingMongoConverter.read(MongoDbMessageStore.java:485)
at org.springframework.data.mongodb.core.MongoTemplate$ReadDbObjectCallback.doWith(MongoTemplate.java:2324)
at org.springframework.data.mongodb.core.MongoTemplate.executeFindMultiInternal(MongoTemplate.java:1969)
at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:1787)
at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:1770)
at org.springframework.data.mongodb.core.MongoTemplate.find(MongoTemplate.java:644)
at org.springframework.data.mongodb.core.MongoTemplate.findOne(MongoTemplate.java:609)
at org.springframework.integration.mongodb.store.MongoDbMessageStore.getMessageGroup(MongoDbMessageStore.java:245)
at org.springframework.integration.store.AbstractMessageGroupStore.addMessageToGroup(AbstractMessageGroupStore.java:210)
at org.springframework.integration.aggregator.AbstractCorrelatingMessageHandler.store(AbstractCorrelatingMessageHandler.java:621)
at org.springframework.integration.aggregator.AbstractCorrelatingMessageHandler.handleMessageInternal(AbstractCorrelatingMessageHandler.java:413)
at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:127)
... 9 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.messaging.support.GenericMessage]: No default constructor found; nested exception is java.lang.NoSuchMethodException: org.springframework.messaging.support.GenericMessage.<init>()
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:105)
at org.springframework.data.convert.ReflectionEntityInstantiator.createInstance(ReflectionEntityInstantiator.java:61)
... 28 common frames omitted
Caused by: java.lang.NoSuchMethodException: org.springframework.messaging.support.GenericMessage.<init>()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.getDeclaredConstructor(Class.java:2178)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:102)
... 29 common frames omitted
我已经使用 Spring Integration DSL 设置了聚合器,如下所示:
I've set up the aggregator with Spring Integration DSL as follows:
IntegrationFlows
.from(
Amqp.inboundAdapter(connectionFactory, properties.getQueue())
.errorChannel(errorChannel)
.mappedRequestHeaders(MAPPED_AMQP_HEADERS)
.taskExecutor(amqpConsumerExecutor)
.concurrentConsumers(properties.getConcurrentConsumers())
.messageConverter(new Jackson2JsonMessageConverter())
.defaultRequeueRejected(false)
)
.channel(resultChannel)
.aggregate(aggregator -> aggregator
.expireGroupsUponCompletion(true)
.groupTimeout(properties.getGroupTimeout())
.expireGroupsUponTimeout(true)
.messageStore(new MongoDbMessageStore(mongoDbFactory))
.outputProcessor(new ResponseAggregator())
)
// ...
mongoDbFactory
由 Spring Boot 自动配置.
The mongoDbFactory
is autoconfigured by Spring Boot.
消息在 MongoDB 中持久化:
The message persisted in MongoDB:
{
"_id" : ObjectId("59ca5c1349ac540d17911afc"),
"_createdDate" : NumberLong(1506434067236),
"_class" : "org.springframework.integration.mongodb.store.MongoDbMessageStore$MessageWrapper",
"_groupId" : "39f292df-4b75-6531-e570-1950ef6bb8e2",
"_messageType" : "org.springframework.messaging.support.GenericMessage",
"payload" : {
"_class" : "com.example.Response",
"status" : 0
},
"headers" : {
"amqp_receivedDeliveryMode" : "PERSISTENT",
"sequenceNumber" : 1,
"amqp_deliveryTag" : NumberLong(3),
"sequenceSize" : 15,
"amqp_consumerQueue" : "response",
"amqp_redelivered" : false,
"amqp_receivedRoutingKey" : "response",
"amqp_contentEncoding" : "UTF-8",
"json__TypeId__" : "com.example.Response",
"correlationId" : "39f292df-4b75-6531-e570-1950ef6bb8e2",
"id" : LUUID("fcf5ba73-30a0-1674-2767-d9980c09fb49"),
"amqp_consumerTag" : "amq.ctag-A0tTqrEhhbEDxN5OEGs3hA",
"contentType" : "application/json",
"timestamp" : NumberLong(1506434067171)
},
"_group_timestamp" : NumberLong(1506434067179),
"_group_update_timestamp" : NumberLong(1506434067179),
"_last_released_sequence" : 0,
"_group_complete" : false,
"sequence" : 2
}
我做错了什么?
推荐答案
您必须将 MongoDbMessageStore
声明为 bean:
You have to declare MongoDbMessageStore
as a bean:
@Bean
MongoDbMessageStore messageStore() {
return new MongoDbMessageStore(mongoDbFactory);
}
...
.messageStore(messageStore())
它具有特定的 BeanFactoryAware
逻辑,包括:
It has particular BeanFactoryAware
logic including:
public void afterPropertiesSet() throws Exception {
if (this.applicationContext != null) {
this.converter.setApplicationContext(this.applicationContext);
}
this.converter.afterPropertiesSet();
MessageReadingMongoConverter
执行的逻辑如下:
public void afterPropertiesSet() {
List<Object> customConverters = new ArrayList<Object>();
customConverters.add(new UuidToDBObjectConverter());
customConverters.add(new DBObjectToUUIDConverter());
customConverters.add(new MessageHistoryToDBObjectConverter());
customConverters.add(new DBObjectToGenericMessageConverter());
customConverters.add(new DBObjectToMutableMessageConverter());
DBObjectToErrorMessageConverter docToErrorMessageConverter = new DBObjectToErrorMessageConverter();
if (MongoDbMessageStore.this.whiteListPatterns != null) {
docToErrorMessageConverter.deserializingConverter
.addWhiteListPatterns(MongoDbMessageStore.this.whiteListPatterns);
}
customConverters.add(docToErrorMessageConverter);
customConverters.add(new DBObjectToAdviceMessageConverter());
customConverters.add(new ThrowableToBytesConverter());
this.setCustomConversions(new CustomConversions(customConverters));
super.afterPropertiesSet();
}
注意DBObjectToGenericMessageConverter
.这就是 GenericMessage
将如何实例化而不是基于默认构造函数的策略.
Pay attention to the DBObjectToGenericMessageConverter
. That is how GenericMessage
will be instantiate instead of default constructor-based strategy.
这篇关于Spring Integration Aggregator 与 MongoDbMessageStore:无法实例化 GenericMessage:未找到默认构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!