Skip to content

Introduce dedicated interface to listen for ClassPathChangedEvents. #17291

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

odrotbohm
Copy link
Member

@odrotbohm odrotbohm commented Jun 21, 2019

So far, LocalDevToolsAutoConfiguration had registered a Lambda-based event listener for ClassPathChangedEvents. As the generics information is not available for lookup from a Lambda defined generic interface, SimpleApplicationEventMulticaster.doInvokeListener(…) has no chance but to submit all events published to the listener, catching the ClassCastExceptions resulting from that to log them into the TRACE level.

For applications that produce a lot of events (esp. during startup) like ones that use Spring Data MongoDB which uses the events to trigger index creation etc., this means that a lot of exceptions are thrown and ultimately discarded most of the time.

This commit introduces a dedicated interface for that particular application listener so that it can be discarded for all events but the one it's really interested in, thus avoiding the superfluous exceptions being produced and ultimately leading to better (startup) performance.

This was tested using Spring Data Examples (rest/starbucks) and lead to a startup time improvement of ~500ms. The example uses Spring Data MongoDB whose object mapping is heavily making use of application events when reading and writing objects to the database. I assume the effect will be less visible in applications using application events less intensively.

So far, LocalDevToolsAutoConfiguration had registered a Lambda-based event listener for ClassPathChangedEvents. As the generics information is not available for lookup from a Lambda defined generic interface, SimpleApplicationEventMulticaster.doInvokeListener(…) has no chance but to submit *all* events published to the listener, catching the ClassCastExceptions resulting from that to log them into the TRACE level.

For applications that produce a lot of events (esp. during startup) like ones that use Spring Data MongoDB which uses the events to trigger index creation etc., this means that a lot of exceptions are thrown and ultimately discarded most of the time.

This commit introduces a dedicated interface for that particular application listener so that it can be discarded for all events but the one it's really interested in, thus avoiding the superfluous exceptions being produced and ultimately leading to better (startup) performance.

This was tested using Spring Data Examples (rest/starbucks) and lead to a startup time improvement of ~500ms. The example uses Spring Data MongoDB whose object mapping is heavily making use of application events when reading and writing objects to the database. I assume the effect will be less visible in applications using application events less intensively.
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jun 21, 2019
@philwebb
Copy link
Member

It's a shame we need to do this because the generics are available in the bytecode, it's just that they're on the factory method and not the bean instance.

@philwebb
Copy link
Member

I've raise spring-projects/spring-framework#23178 to see if there's not a more general solution that Framework can apply. If they can't we'll do the change in Boot.

@philwebb philwebb added type: enhancement A general enhancement and removed status: on-hold We can't start working on this issue yet status: waiting-for-triage An issue we've not yet triaged labels Jun 21, 2019
@philwebb philwebb added this to the 2.2.x milestone Jun 21, 2019
@snicoll snicoll added the status: blocked An issue that's blocked on an external project change label Jul 16, 2019
@wilkinsona
Copy link
Member

Looks like Framework has taken care of this for us.

@wilkinsona wilkinsona closed this Jul 21, 2019
@wilkinsona wilkinsona removed this from the 2.2.x milestone Jul 21, 2019
@wilkinsona wilkinsona added status: superseded An issue that has been superseded by another and removed status: blocked An issue that's blocked on an external project change type: enhancement A general enhancement labels Jul 21, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: superseded An issue that has been superseded by another
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants