spring-projects / spring-framework

Spring Framework
https://spring.io/projects/spring-framework
Apache License 2.0
56.49k stars 38.1k forks source link

Reduce the impact on startup time of adding Reactor to the classpath [SPR-16981] #21519

Closed spring-projects-issues closed 6 years ago

spring-projects-issues commented 6 years ago

Andy Wilkinson opened SPR-16981 and commented

I've been looking at the performance of ConfigurationClassPostProcessor, particularly the overhead that it adds when are no full or lite configuration classes in the context. As part of this, I've observed that adding Reactor to the classpath has a large impact. Without Reactor on the classpath I see postProcessBeanDefinitionRegistry take 10-20ms. With Reactor on the classpath it can take as much as 100ms to do the same thing (add 0 bean definitions).

The cost is incurred when ConfigurationClassUtils is loaded as it, ultimately, leads to a couple of hundred Reactor classes being loaded. Here's the beginning of the -verbose:class output:

[Loaded org.springframework.context.annotation.ConfigurationClassUtils from file:/Users/awilkinson/dev/workspaces/spring/spring-boot/master/configuration-class-parser-overhead/target/classes/]
[Loaded org.springframework.core.type.ClassMetadata from file:/Users/awilkinson/.m2/repository/org/springframework/spring-core/5.0.5.RELEASE/spring-core-5.0.5.RELEASE.jar]
[Loaded org.springframework.core.type.AnnotationMetadata from file:/Users/awilkinson/.m2/repository/org/springframework/spring-core/5.0.5.RELEASE/spring-core-5.0.5.RELEASE.jar]
[Loaded org.springframework.core.Conventions from file:/Users/awilkinson/.m2/repository/org/springframework/spring-core/5.0.5.RELEASE/spring-core-5.0.5.RELEASE.jar]
[Loaded org.springframework.core.ReactiveAdapterRegistry from file:/Users/awilkinson/.m2/repository/org/springframework/spring-core/5.0.5.RELEASE/spring-core-5.0.5.RELEASE.jar]
[Loaded org.springframework.core.ReactiveAdapterRegistry$ReactorRegistrar from file:/Users/awilkinson/.m2/repository/org/springframework/spring-core/5.0.5.RELEASE/spring-core-5.0.5.RELEASE.jar]
[Loaded org.reactivestreams.Publisher from file:/Users/awilkinson/.m2/repository/org/reactivestreams/reactive-streams/1.0.2/reactive-streams-1.0.2.jar]
[Loaded reactor.core.publisher.Mono from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.Scannable from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoOperator from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoCacheTime from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded org.reactivestreams.Subscriber from file:/Users/awilkinson/.m2/repository/org/reactivestreams/reactive-streams/1.0.2/reactive-streams-1.0.2.jar]
[Loaded org.reactivestreams.Processor from file:/Users/awilkinson/.m2/repository/org/reactivestreams/reactive-streams/1.0.2/reactive-streams-1.0.2.jar]
[Loaded reactor.core.CoreSubscriber from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.Disposable from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded org.reactivestreams.Subscription from file:/Users/awilkinson/.m2/repository/org/reactivestreams/reactive-streams/1.0.2/reactive-streams-1.0.2.jar]
[Loaded java.util.function.LongSupplier from /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/rt.jar]
[Loaded reactor.core.publisher.MonoProcessor from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.SignalPeek from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.Fuseable from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoLogFuseable from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoLog from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoZip from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoFirst from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoCreate from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.Flux from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.FluxFromMonoOperator from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoExpand from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoFilterFuseable from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoFilter from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded java.util.concurrent.Callable from /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/rt.jar]
[Loaded reactor.core.Fuseable$ScalarCallable from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoError from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoMapFuseable from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoMap from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoHandleFuseable from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoHandle from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoFlatMap from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoFromPublisher from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded java.util.concurrent.CompletionStage from /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/rt.jar]
[Loaded reactor.core.publisher.MonoCompletionStage from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoDefer from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoDelay from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoCallable from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoFromFluxOperator from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoSourceFluxFuseable from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoSourceFlux from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoSourceFuseable from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoSource from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoRunnable from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoSupplier from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoIgnorePublisher from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoJust from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoSequenceEqual from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoCurrentContext from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoSubscriberContext from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoUsing from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoWhen from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoTimeout from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoCancelOn from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.AssemblyOp from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoOnAssembly from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoDefaultIfEmpty from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoDelayElement from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoDelayUntil from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded java.util.function.Consumer from /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/rt.jar]
[Loaded reactor.core.publisher.MonoDelaySubscription from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoDematerialize from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoPeekTerminal from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoDoFinallyFuseable from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoDoFinally from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoDoOnEach from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoElapsed from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoFilterWhen from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoFlatMapMany from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoFlattenIterable from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.FluxCallable from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoHasElement from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoHide from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoIgnoreElement from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoMaterialize from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoOnErrorResume from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoDetach from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoPublishMulticast from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoSubscribeOnValue from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoSubscribeOnCallable from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoPublishOn from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoRepeat from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoRepeatPredicate from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoRepeatWhen from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoRetry from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoRetryPredicate from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoRetryWhen from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded java.util.NoSuchElementException from /Library/Java/JavaVirtualMachines/jdk1.8.0_151.jdk/Contents/Home/jre/lib/rt.jar]
[Loaded reactor.core.publisher.MonoSingleMono from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoSubscribeOn from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoSwitchIfEmpty from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoTakeUntilOther from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoIgnoreThen from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoPeekFuseable from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoPeek from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded java.lang.invoke.LambdaForm$DMH/192794887 from java.lang.invoke.LambdaForm]
[Loaded org.springframework.core.ReactiveAdapterRegistry$ReactorRegistrar$$Lambda$9/1391942103 from org.springframework.core.ReactiveAdapterRegistry$ReactorRegistrar]
[Loaded org.springframework.core.ReactiveTypeDescriptor from file:/Users/awilkinson/.m2/repository/org/springframework/spring-core/5.0.5.RELEASE/spring-core-5.0.5.RELEASE.jar]
[Loaded org.springframework.core.ReactiveAdapterRegistry$ReactorRegistrar$$Lambda$10/1136497418 from org.springframework.core.ReactiveAdapterRegistry$ReactorRegistrar]
[Loaded java.lang.invoke.LambdaForm$DMH/863125040 from java.lang.invoke.LambdaForm]
[Loaded org.springframework.core.ReactiveAdapterRegistry$ReactorRegistrar$$Lambda$11/1693847660 from org.springframework.core.ReactiveAdapterRegistry$ReactorRegistrar]
[Loaded org.springframework.core.ReactiveAdapter from file:/Users/awilkinson/.m2/repository/org/springframework/spring-core/5.0.5.RELEASE/spring-core-5.0.5.RELEASE.jar]
[Loaded reactor.core.publisher.FluxOperator from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.FluxIndexFuseable from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.FluxIndex from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoCount from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.FluxLogFuseable from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.FluxLog from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.FluxConcatArray from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.FluxConcatIterable from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.FluxConcatMap from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.FluxJoin from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoNext from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoCollect from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoStreamCollector from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.MonoElementAt from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.FluxCreate from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.FluxZip from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.FluxMapFuseable from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.FluxMap from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.FluxFirstEmitting from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.FluxMerge from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.FluxFlatMap from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.FluxSourceMonoFuseable from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.FluxSourceMono from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.FluxSourceFuseable from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.FluxSource from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
[Loaded reactor.core.publisher.FluxExpand from file:/Users/awilkinson/.m2/repository/io/projectreactor/reactor-core/3.1.6.RELEASE/reactor-core-3.1.6.RELEASE.jar]
…

The javadoc on ReactiveAdapterRegistry.getSharedInstance() indicates that the instance is lazily built. This is undone by Conventions which stores the shared instance in a static field, thereby triggering creation of the instance as soon as the class is loaded.

The registry is only used in getVariableNameForParameter and getVariableNameForReturnType. In the application that I have been examining, neither method is called during startup. Perhaps the initialisation of the registry could be deferred until it's needed?

Beyond deferring the initialisation, I wonder if there's something that can be done to reduce the impact when it is eventually needed? The cost in terms of time and metaspace usage of loading 250 classes seems rather high.


Affects: 5.0.7

Issue Links:

Referenced from: commits https://github.com/spring-projects/spring-framework/commit/b68e692854d4494c141259c924c667c21784c3eb, https://github.com/spring-projects/spring-framework/commit/3e64388b20e4f885b29f388e3e5bca55cd1a4cec

spring-projects-issues commented 6 years ago

Juergen Hoeller commented

I'm rolling this into my bunch of commits coming up here, at least the part where Conventions lazily retrieves the shared ReactiveAdapterRegistry. Whether we could revise Conventions to not require loading of so many Reactor classes is a separate question (Rossen Stoyanchev)... but then if Reactor is actually on the classpath, I suppose it'll be used at some point anyway?

spring-projects-issues commented 6 years ago

Andy Wilkinson commented

I suppose it'll be used at some point anyway?

Yes. If you're using WebFlux, WebFluxConfigurationSupport.webFluxAdapterRegistry() will trigger the loading of all the Reactor classes as it creates a new ReactiveAdapterRegistry.

spring-projects-issues commented 6 years ago

Rossen Stoyanchev commented

The RecativeAdapterRegistry API was updated once before (for Spring Data, #19468) to not depend on the presence of Reactor. Of course, if Reactor is present, Reactor classes are loaded in the constructor.

For WebFlux the registry is necessary to work with reactive types in controller method signatures, so could be deferred but very likely to be used although there could be exceptions (e.g. functional endpoints). For Spring MVC, RequestMappingHandlerAdapter declares it as a field, but it will only be used with reactive types as return values in controller methods.

spring-projects-issues commented 6 years ago

Andy Wilkinson commented

Thanks, Rossen. I'm in favour of deferring as much as is reasonably possible. It perhaps makes most sense in the functional endpoint case where one reason to use them is that they should perform better (no reflection, no annotation introspection, etc). Deferring in the MVC case perhaps makes sense too. It would mean that the price is only paid when there is a controller with a Reactor return type. Should I open a separate issue or can this one continue to be used?

spring-projects-issues commented 6 years ago

Juergen Hoeller commented

Alright, I'll have a look at the web module usage of ReactiveAdapterRegistry, considering a backport to 5.0.8 (like for the Conventions refinement) as well.

spring-projects-issues commented 6 years ago

Andy Wilkinson commented

Thanks, Juergen. Both for this issue and the various other changes you've made for us recently.

spring-projects-issues commented 6 years ago

Juergen Hoeller commented

Andy Wilkinson, after revisiting all usage there, access to ReactiveAdapterRegistry seems as deferred as reasonably possible already...

In the functional web case, we don't ever instantiate a ReactiveAdapterRegistry to begin with. In the annotation-based case (both for WebFlux and for MVC), we need the registry to identify supported reactive return types, and the actual registry is configurable... so it'd be rather artificial to defer access to the registry.

Trying to separate identification and adaptation there seems like a micro-optimization which would create complexity without much of a benefit, so I'd rather leave things as-is. If Reactor is present on the classpath, it seems reasonable to register its adapters once annotation-based web endpoint processing is set up.

spring-projects-issues commented 6 years ago

Rossen Stoyanchev commented

Just one note. ReactiveAdapterRegistry indeed is not instantiated when bootstrapping the server manually. In the context of a Boot application however, applications declare RouterFunction beans that in turn rely on RouterFunctionMapping declared in WebFluxConfigurationSupport that also creates a ReactiveAdapterRegistry.