From 429cd8d114e56e5802174d94564c3726a2ebc8c7 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 23 Aug 2018 14:09:48 +0200 Subject: [PATCH] Optimize use of Jackson ObjectMapper instances Closes gh-1789 --- ...ConfigurationPropertiesReportEndpoint.java | 14 ++++++++++--- .../boot/json/JacksonJsonParser.java | 14 +++++++++++++ .../boot/json/JacksonJsonParserTests.java | 21 ++++++++++++++++++- 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpoint.java b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpoint.java index 06515af9e67..4304ab6c3e8 100644 --- a/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpoint.java +++ b/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/context/properties/ConfigurationPropertiesReportEndpoint.java @@ -79,6 +79,8 @@ public class ConfigurationPropertiesReportEndpoint implements ApplicationContext private ApplicationContext context; + private ObjectMapper objectMapper; + @Override public void setApplicationContext(ApplicationContext context) throws BeansException { this.context = context; @@ -94,13 +96,11 @@ public class ConfigurationPropertiesReportEndpoint implements ApplicationContext } private ApplicationConfigurationProperties extract(ApplicationContext context) { - ObjectMapper mapper = new ObjectMapper(); - configureObjectMapper(mapper); Map contextProperties = new HashMap<>(); ApplicationContext target = context; while (target != null) { contextProperties.put(target.getId(), - describeConfigurationProperties(target, mapper)); + describeConfigurationProperties(target, getObjectMapper())); target = target.getParent(); } return new ApplicationConfigurationProperties(contextProperties); @@ -179,6 +179,14 @@ public class ConfigurationPropertiesReportEndpoint implements ApplicationContext applySerializationModifier(mapper); } + private ObjectMapper getObjectMapper() { + if (this.objectMapper == null) { + this.objectMapper = new ObjectMapper(); + configureObjectMapper(this.objectMapper); + } + return this.objectMapper; + } + /** * Ensure only bindable and non-cyclic bean properties are reported. * @param mapper the object mapper diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/json/JacksonJsonParser.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/json/JacksonJsonParser.java index 41651fa1df0..11f13e757b0 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/json/JacksonJsonParser.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/json/JacksonJsonParser.java @@ -36,6 +36,20 @@ public class JacksonJsonParser extends AbstractJsonParser { private ObjectMapper objectMapper; // Late binding + /** + * Creates a instance with the specified {@link ObjectMapper}. + * @param objectMapper the object mapper to use + */ + public JacksonJsonParser(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + /** + * Creates an instance with a default {@link ObjectMapper} that is created lazily. + */ + public JacksonJsonParser() { + } + @Override public Map parseMap(String json) { return tryParse(() -> getObjectMapper().readValue(json, MAP_TYPE), diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/json/JacksonJsonParserTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/json/JacksonJsonParserTests.java index 031a4662bba..e0914409c47 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/json/JacksonJsonParserTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/json/JacksonJsonParserTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 the original author or authors. + * Copyright 2012-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,10 +16,22 @@ package org.springframework.boot.json; +import java.io.IOException; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Test; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + /** * Tests for {@link JacksonJsonParser}. * * @author Dave Syer + * @author Stephane Nicoll */ public class JacksonJsonParserTests extends AbstractJsonParserTests { @@ -28,4 +40,11 @@ public class JacksonJsonParserTests extends AbstractJsonParserTests { return new JacksonJsonParser(); } + @Test + public void instanceWithSpecificObjectMapper() throws IOException { + ObjectMapper objectMapper = spy(new ObjectMapper()); + new JacksonJsonParser(objectMapper).parseMap("{}"); + verify(objectMapper).readValue(eq("{}"), any(TypeReference.class)); + } + }