diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/BackgroundPreinitializer.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/BackgroundPreinitializer.java index f1008e2b481..29f52a61572 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/BackgroundPreinitializer.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/BackgroundPreinitializer.java @@ -16,11 +16,17 @@ package org.springframework.boot.autoconfigure; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicBoolean; + import javax.validation.Validation; import org.apache.catalina.mbeans.MBeanFactory; import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; +import org.springframework.boot.context.event.ApplicationFailedEvent; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.boot.context.event.SpringApplicationEvent; import org.springframework.boot.context.logging.LoggingApplicationListener; import org.springframework.context.ApplicationListener; import org.springframework.core.annotation.Order; @@ -38,10 +44,31 @@ import org.springframework.http.converter.support.AllEncompassingFormHttpMessage */ @Order(LoggingApplicationListener.DEFAULT_ORDER + 1) public class BackgroundPreinitializer - implements ApplicationListener { + implements ApplicationListener { + + private static final AtomicBoolean preinitalizationStarted = new AtomicBoolean(false); + + private static final CountDownLatch preinitializationComplete = new CountDownLatch(1); @Override - public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) { + public void onApplicationEvent(SpringApplicationEvent event) { + if (event instanceof ApplicationEnvironmentPreparedEvent) { + if (preinitalizationStarted.compareAndSet(false, true)) { + performPreinitialization(); + } + } + if (event instanceof ApplicationReadyEvent + || event instanceof ApplicationFailedEvent) { + try { + preinitializationComplete.await(); + } + catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + } + } + } + + private void performPreinitialization() { try { Thread thread = new Thread(new Runnable() { @@ -52,6 +79,7 @@ public class BackgroundPreinitializer runSafely(new ValidationInitializer()); runSafely(new JacksonInitializer()); runSafely(new ConversionServiceInitializer()); + preinitializationComplete.countDown(); } public void runSafely(Runnable runnable) { @@ -70,6 +98,7 @@ public class BackgroundPreinitializer // This will fail on GAE where creating threads is prohibited. We can safely // continue but startup will be slightly slower as the initialization will now // happen on the main thread. + preinitializationComplete.countDown(); } }