From 5182bc4f2b1e7811b91ab857ddd325cc031d5805 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Wed, 22 Jun 2016 20:37:59 -0700 Subject: [PATCH] Improve startup times Improve startup times (although not by much) by adding more background pre-initializers and lazily evaluating the whitelabel SpEL view. See gh-6177 --- .../BackgroundPreinitializer.java | 28 +++++++++++++++++++ .../web/ErrorMvcAutoConfiguration.java | 18 ++++++++---- 2 files changed, 41 insertions(+), 5 deletions(-) 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 b9c5462ca8..fd94188507 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 @@ -24,6 +24,8 @@ import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEven import org.springframework.boot.logging.LoggingApplicationListener; import org.springframework.context.ApplicationListener; import org.springframework.core.annotation.Order; +import org.springframework.format.support.DefaultFormattingConversionService; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter; /** @@ -48,6 +50,8 @@ public class BackgroundPreinitializer runSafely(new MessageConverterInitializer()); runSafely(new MBeanFactoryInitializer()); runSafely(new ValidationInitializer()); + runSafely(new JacksonInitializer()); + runSafely(new ConverstionServiceInitializer()); } public void runSafely(Runnable runnable) { @@ -105,4 +109,28 @@ public class BackgroundPreinitializer } + /** + * Early initializer for Jackson. + */ + private static class JacksonInitializer implements Runnable { + + @Override + public void run() { + Jackson2ObjectMapperBuilder.json().build(); + } + + } + + /** + * Early initializer for Spring's ConverstionService. + */ + private static class ConverstionServiceInitializer implements Runnable { + + @Override + public void run() { + new DefaultFormattingConversionService(); + } + + } + } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ErrorMvcAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ErrorMvcAutoConfiguration.java index a89538e0e6..41f7db057e 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ErrorMvcAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ErrorMvcAutoConfiguration.java @@ -189,14 +189,11 @@ public class ErrorMvcAutoConfiguration { private final String template; - private final Map expressions; + private volatile Map expressions; SpelView(String template) { this.helper = new NonRecursivePropertyPlaceholderHelper("${", "}"); this.template = template; - ExpressionCollector expressionCollector = new ExpressionCollector(); - this.helper.replacePlaceholders(this.template, expressionCollector); - this.expressions = expressionCollector.getExpressions(); } @Override @@ -212,11 +209,22 @@ public class ErrorMvcAutoConfiguration { } Map map = new HashMap(model); map.put("path", request.getContextPath()); - PlaceholderResolver resolver = new ExpressionResolver(this.expressions, map); + PlaceholderResolver resolver = new ExpressionResolver(getExpressions(), map); String result = this.helper.replacePlaceholders(this.template, resolver); response.getWriter().append(result); } + private Map getExpressions() { + if (this.expressions == null) { + synchronized (this) { + ExpressionCollector expressionCollector = new ExpressionCollector(); + this.helper.replacePlaceholders(this.template, expressionCollector); + this.expressions = expressionCollector.getExpressions(); + } + } + return this.expressions; + } + } /**