Skip to content

Commit 881c6bc

Browse files
committed
Dirty hack to demonstrate that reusing the context improves performance significantly
1 parent d31b3c1 commit 881c6bc

File tree

2 files changed

+37
-10
lines changed

2 files changed

+37
-10
lines changed

springdoc-openapi-starter-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
import org.springdoc.core.service.OpenAPIService;
110110
import org.springdoc.core.service.OperationService;
111111
import org.springdoc.core.utils.PropertyResolverUtils;
112+
import org.springdoc.core.utils.SpringDocAnnotationsUtils;
112113
import org.springdoc.core.utils.SpringDocUtils;
113114

114115
import org.springframework.aop.support.AopUtils;
@@ -349,6 +350,7 @@ protected OpenAPI getOpenApi(String serverBaseUrl, Locale locale) {
349350
final OpenAPI openAPI;
350351
final Locale finalLocale = selectLocale(locale);
351352
if (openAPIService.getCachedOpenAPI(finalLocale) == null || springDocConfigProperties.isCacheDisabled()) {
353+
SpringDocAnnotationsUtils.CONTEXT.clear();
352354
Instant start = Instant.now();
353355
openAPI = openAPIService.build(finalLocale);
354356
Map<String, Object> mappingsMap = openAPIService.getMappingsMap().entrySet().stream()

springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocAnnotationsUtils.java

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import java.util.ArrayList;
3333
import java.util.Arrays;
3434
import java.util.Collections;
35+
import java.util.HashMap;
3536
import java.util.LinkedHashMap;
3637
import java.util.LinkedHashSet;
3738
import java.util.List;
@@ -44,6 +45,8 @@
4445
import com.fasterxml.jackson.annotation.JsonView;
4546
import com.fasterxml.jackson.databind.ObjectMapper;
4647
import io.swagger.v3.core.converter.AnnotatedType;
48+
import io.swagger.v3.core.converter.ModelConverterContext;
49+
import io.swagger.v3.core.converter.ModelConverterContextImpl;
4750
import io.swagger.v3.core.converter.ModelConverters;
4851
import io.swagger.v3.core.converter.ResolvedSchema;
4952
import io.swagger.v3.core.util.AnnotationsUtils;
@@ -63,6 +66,7 @@
6366
import io.swagger.v3.oas.models.media.StringSchema;
6467
import org.apache.commons.lang3.ArrayUtils;
6568
import org.apache.commons.lang3.StringUtils;
69+
import org.jetbrains.annotations.Nullable;
6670
import org.slf4j.Logger;
6771
import org.slf4j.LoggerFactory;
6872

@@ -91,6 +95,11 @@ public class SpringDocAnnotationsUtils extends AnnotationsUtils {
9195
*/
9296
private static final List<Class> ANNOTATIONS_TO_IGNORE = Collections.synchronizedList(new ArrayList<>());
9397

98+
/**
99+
* The reusable context
100+
*/
101+
public static final Map<SpecVersion, ModelConverterContext> CONTEXT = new HashMap<>();
102+
94103
static {
95104
ANNOTATIONS_TO_IGNORE.add(Hidden.class);
96105
ANNOTATIONS_TO_IGNORE.add(JsonIgnore.class);
@@ -131,18 +140,15 @@ public static Schema resolveSchemaFromType(Class<?> schemaImplementation, Compon
131140
public static Schema extractSchema(Components components, Type returnType, JsonView jsonView, Annotation[] annotations, SpecVersion specVersion) {
132141
if (returnType == null) return null;
133142
Schema schemaN = null;
134-
ResolvedSchema resolvedSchema;
135143
boolean openapi31 = SpecVersion.V31 == specVersion;
136-
try {
137-
resolvedSchema = ModelConverters.getInstance(openapi31)
138-
.resolveAsResolvedSchema(
139-
new AnnotatedType(returnType)
140-
.resolveAsRef(true).jsonViewAnnotation(jsonView).ctxAnnotations(annotations));
141-
}
142-
catch (Exception e) {
143-
LOGGER.warn(Constants.GRACEFUL_EXCEPTION_OCCURRED, e);
144-
return null;
144+
if (jsonView != null) {
145+
annotations = ArrayUtils.addAll(annotations, jsonView);
145146
}
147+
var aType = new AnnotatedType(returnType)
148+
.resolveAsRef(true)
149+
.jsonViewAnnotation(jsonView)
150+
.ctxAnnotations(annotations);
151+
ResolvedSchema resolvedSchema = resolveAsResolvedSchema(specVersion, aType);
146152
if (resolvedSchema != null) {
147153
Map<String, Schema> schemaMap = resolvedSchema.referencedSchemas;
148154
if (!CollectionUtils.isEmpty(schemaMap) && components != null) {
@@ -187,6 +193,25 @@ else if (componentSchemas.containsKey(entry.getKey()) && schemaMap.containsKey(e
187193
return schemaN;
188194
}
189195

196+
@Nullable
197+
private static ResolvedSchema resolveAsResolvedSchema(SpecVersion specVersion, AnnotatedType type) {
198+
ResolvedSchema resolvedSchema;
199+
try {
200+
var context = CONTEXT.computeIfAbsent(specVersion, k -> {
201+
boolean openapi31 = SpecVersion.V31 == specVersion;
202+
return new ModelConverterContextImpl(ModelConverters.getInstance(openapi31).getConverters());
203+
});
204+
resolvedSchema = new ResolvedSchema();
205+
resolvedSchema.schema = context.resolve(type);
206+
resolvedSchema.referencedSchemas = context.getDefinedModels();
207+
}
208+
catch (Exception e) {
209+
LOGGER.warn(Constants.GRACEFUL_EXCEPTION_OCCURRED, e);
210+
return null;
211+
}
212+
return resolvedSchema;
213+
}
214+
190215
/**
191216
* Gets content.
192217
*

0 commit comments

Comments
 (0)