Description
lnevaril opened DATAMONGO-2129 and commented
Framework spring-data-mongodb
provides possibility to register own listeners for the lifecycle events through extending generic AbstractMongoEventListener<T>
. All lifecycle events are processed by SimpleApplicationEventMulticaster
and corresponding listeners are invoked. For each lifecycle event all listeners extending AbstractMongoEventListener
are invoked even though the generic type is different and the filtering is done in AbstractMongoEventListener
instances method onApplicationEvent
but it could be done in the higher level in the event multicaster through existing facility. This fact has significant performance impact on the database queries (in our application by order of magnitude for findAll
operations). Spring framework offers possibility to determine the type of generic events correctly by implementing ResolvableTypeProvider,
for example org.springframework.context.PayloadApplicationEvent
implements it. Is there any reason to not to implement the ResolvableTypeProvider
interface in the MongoMappingEvent
to reduce the number of invoked listeners for all lifecycle events only to the desired ones? For example during the findAll
operation on collection it would reduce the overhead of calling all listeners for each collection's object.
Consider following example:
There are three simple classes User
, Category
and Item
and for each domain object there is a repository. Moreover, there are AbstractMongoEventListeners
for each domain object.
@Component
public class UserMongoEventListener extends AbstractMongoEventListener<User> {
@Override
public void onAfterLoad(AfterLoadEvent<User> event) {
super.onAfterLoad(event);
}
@Override
public void onAfterConvert(AfterConvertEvent<User> event) {
super.onAfterConvert(event);
}
@Override
public void onBeforeConvert(BeforeConvertEvent<User> event) {
super.onBeforeConvert(event);
}
}
@Component
public class CategoryMongoEventListener extends AbstractMongoEventListener<Category> {
@Override
public void onAfterLoad(AfterLoadEvent<Category> event) {
super.onAfterLoad(event);
}
@Override
public void onAfterConvert(AfterConvertEvent<Category> event) {
super.onAfterConvert(event);
}
@Override
public void onBeforeConvert(BeforeConvertEvent<Category> event) {
super.onBeforeConvert(event);
}
}
@Component
public class ItemMongoEventListener extends AbstractMongoEventListener<Item> {
@Override
public void onAfterLoad(AfterLoadEvent<Item> event) {
super.onAfterLoad(event);
}
@Override
public void onAfterConvert(AfterConvertEvent<Item> event) {
super.onAfterConvert(event);
}
@Override
public void onBeforeConvert(BeforeConvertEvent<Item> event) {
super.onBeforeConvert(event);
}
}
Consider there are 1000 Item
objects in the database and findAll
method is called on this collection. Events AfterLoadEvent
and AfterConvertEvent
are published for each Item
document.
By default event multicasting is done by SimpleApplicationEventMulticaster.
ResolvableType
of MongoMappingEvent
is org.springframework.data.mongodb.core.mapping.event.AfterLoadEvent<?>
, therefore, getApplicationListeners(event, type)
returns all defined AbstractMongoEventListener
instances (in fact it returns all listeners registered for Spring's ApplicationEvent
).
org.springframework.context.event.SimpleApplicationEventMulticaster
@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);
}
}
}
This would result in 4000 unnecessary calls to listeners defined for different domain type since ResolvableType
of MongoMappingEvent
's does not provide information of the exact generic parameter type.
Is there any reason for this behavior that I do not understand? Possibly I could contribute with the pull request to extend MongoMappingEvent
with the ResolvableTypeProvider
.
Thank you
No further details from DATAMONGO-2129