Skip to content

Commit 5ad5087

Browse files
committed
Ordering of GlobalOpenApiCustomizers different than for OpenApiCustomisers. Fixes #2107
1 parent c664a83 commit 5ad5087

File tree

17 files changed

+399
-68
lines changed

17 files changed

+399
-68
lines changed

springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocConfiguration.java

+7-2
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
import org.springdoc.core.customizers.ServerBaseUrlCustomizer;
6868
import org.springdoc.core.customizers.SpringDocCustomizers;
6969
import org.springdoc.core.discoverer.SpringDocParameterNameDiscoverer;
70+
import org.springdoc.core.filters.GlobalOpenApiMethodFilter;
7071
import org.springdoc.core.filters.OpenApiMethodFilter;
7172
import org.springdoc.core.models.GroupedOpenApi;
7273
import org.springdoc.core.parsers.ReturnTypeParser;
@@ -595,6 +596,9 @@ public ResponseEntity<ErrorMessage> handleNoHandlerFound(OpenApiResourceNotFound
595596
* @param routerOperationCustomizers the router operation customizers
596597
* @param dataRestRouterOperationCustomizers the data rest router operation customizers
597598
* @param methodFilters the method filters
599+
* @param globalOpenApiCustomizers the global open api customizers
600+
* @param globalOperationCustomizers the global operation customizers
601+
* @param globalOpenApiMethodFilters the global open api method filters
598602
* @return the spring doc customizers
599603
*/
600604
@Bean
@@ -604,11 +608,12 @@ public SpringDocCustomizers springDocCustomizers(Optional<List<OpenApiCustomizer
604608
Optional<List<OperationCustomizer>> operationCustomizers,
605609
Optional<List<RouterOperationCustomizer>> routerOperationCustomizers,
606610
Optional<List<DataRestRouterOperationCustomizer>> dataRestRouterOperationCustomizers,
607-
Optional<List<OpenApiMethodFilter>> methodFilters){
611+
Optional<List<OpenApiMethodFilter>> methodFilters, Optional<List<GlobalOpenApiCustomizer>> globalOpenApiCustomizers, Optional<List<GlobalOperationCustomizer>> globalOperationCustomizers,
612+
Optional<List<GlobalOpenApiMethodFilter>> globalOpenApiMethodFilters){
608613
return new SpringDocCustomizers(openApiCustomizers,
609614
operationCustomizers,
610615
routerOperationCustomizers,
611616
dataRestRouterOperationCustomizers,
612-
methodFilters);
617+
methodFilters, globalOpenApiCustomizers, globalOperationCustomizers, globalOpenApiMethodFilters);
613618
}
614619
}

springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/SpringDocCustomizers.java

+52-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import java.util.Objects;
2929
import java.util.Optional;
3030

31+
import org.springdoc.core.filters.GlobalOpenApiMethodFilter;
3132
import org.springdoc.core.filters.OpenApiMethodFilter;
3233

3334
import org.springframework.beans.BeansException;
@@ -76,6 +77,21 @@ public class SpringDocCustomizers implements ApplicationContextAware, Initializi
7677
*/
7778
private final Optional<List<OpenApiMethodFilter>> methodFilters;
7879

80+
/**
81+
* The Global open api customizers.
82+
*/
83+
private Optional<List<GlobalOpenApiCustomizer>> globalOpenApiCustomizers;
84+
85+
/**
86+
* The Global operation customizers.
87+
*/
88+
private Optional<List<GlobalOperationCustomizer>> globalOperationCustomizers;
89+
90+
/**
91+
* The Global open api method filters.
92+
*/
93+
private Optional<List<GlobalOpenApiMethodFilter>> globalOpenApiMethodFilters;
94+
7995

8096
/**
8197
* Instantiates a new Spring doc customizers.
@@ -85,14 +101,22 @@ public class SpringDocCustomizers implements ApplicationContextAware, Initializi
85101
* @param routerOperationCustomizers the router operation customizers
86102
* @param dataRestRouterOperationCustomizers the data rest router operation customizers
87103
* @param methodFilters the method filters
104+
* @param globalOpenApiCustomizers the global open api customizers
105+
* @param globalOperationCustomizers the global operation customizers
106+
* @param globalOpenApiMethodFilters the global open api method filters
88107
*/
89108
public SpringDocCustomizers(Optional<List<OpenApiCustomizer>> openApiCustomizers,
90109
Optional<List<OperationCustomizer>> operationCustomizers,
91110
Optional<List<RouterOperationCustomizer>> routerOperationCustomizers,
92111
Optional<List<DataRestRouterOperationCustomizer>> dataRestRouterOperationCustomizers,
93-
Optional<List<OpenApiMethodFilter>> methodFilters) {
112+
Optional<List<OpenApiMethodFilter>> methodFilters,
113+
Optional<List<GlobalOpenApiCustomizer>> globalOpenApiCustomizers, Optional<List<GlobalOperationCustomizer>> globalOperationCustomizers,
114+
Optional<List<GlobalOpenApiMethodFilter>> globalOpenApiMethodFilters) {
94115
this.openApiCustomizers = openApiCustomizers;
95116
this.operationCustomizers = operationCustomizers;
117+
this.globalOpenApiCustomizers = globalOpenApiCustomizers;
118+
this.globalOperationCustomizers = globalOperationCustomizers;
119+
this.globalOpenApiMethodFilters = globalOpenApiMethodFilters;
96120
operationCustomizers.ifPresent(customizers -> customizers.removeIf(Objects::isNull));
97121
this.routerOperationCustomizers = routerOperationCustomizers;
98122
this.dataRestRouterOperationCustomizers = dataRestRouterOperationCustomizers;
@@ -166,6 +190,33 @@ public void setApplicationContext(ApplicationContext applicationContext) throws
166190
this.context = applicationContext;
167191
}
168192

193+
/**
194+
* Gets global open api customizers.
195+
*
196+
* @return the global open api customizers
197+
*/
198+
public Optional<List<GlobalOpenApiCustomizer>> getGlobalOpenApiCustomizers() {
199+
return globalOpenApiCustomizers;
200+
}
201+
202+
/**
203+
* Gets global operation customizers.
204+
*
205+
* @return the global operation customizers
206+
*/
207+
public Optional<List<GlobalOperationCustomizer>> getGlobalOperationCustomizers() {
208+
return globalOperationCustomizers;
209+
}
210+
211+
/**
212+
* Gets global open api method filters.
213+
*
214+
* @return the global open api method filters
215+
*/
216+
public Optional<List<GlobalOpenApiMethodFilter>> getGlobalOpenApiMethodFilters() {
217+
return globalOpenApiMethodFilters;
218+
}
219+
169220
@Override
170221
public void afterPropertiesSet() {
171222
//add the default customizers

springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/api/MultipleOpenApiActuatorResource.java

+7-2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
import com.fasterxml.jackson.core.JsonProcessingException;
3131
import io.swagger.v3.oas.annotations.Operation;
32+
import org.springdoc.core.customizers.SpringDocCustomizers;
3233
import org.springdoc.core.models.GroupedOpenApi;
3334
import org.springdoc.core.properties.SpringDocConfigProperties;
3435
import org.springdoc.core.providers.SpringDocProviders;
@@ -61,16 +62,20 @@ public class MultipleOpenApiActuatorResource extends MultipleOpenApiResource {
6162

6263
/**
6364
* Instantiates a new Multiple open api resource.
65+
*
6466
* @param groupedOpenApis the grouped open apis
6567
* @param defaultOpenAPIBuilder the default open api builder
6668
* @param requestBuilder the request builder
6769
* @param responseBuilder the response builder
6870
* @param operationParser the operation parser
6971
* @param springDocConfigProperties the spring doc config properties
7072
* @param springDocProviders the spring doc providers
73+
* @param springDocCustomizers the spring doc customizers
7174
*/
72-
public MultipleOpenApiActuatorResource(List<GroupedOpenApi> groupedOpenApis, ObjectFactory<OpenAPIService> defaultOpenAPIBuilder, AbstractRequestService requestBuilder, GenericResponseService responseBuilder, OperationService operationParser, SpringDocConfigProperties springDocConfigProperties, SpringDocProviders springDocProviders) {
73-
super(groupedOpenApis, defaultOpenAPIBuilder, requestBuilder, responseBuilder, operationParser, springDocConfigProperties, springDocProviders);
75+
public MultipleOpenApiActuatorResource(List<GroupedOpenApi> groupedOpenApis, ObjectFactory<OpenAPIService> defaultOpenAPIBuilder,
76+
AbstractRequestService requestBuilder, GenericResponseService responseBuilder, OperationService operationParser,
77+
SpringDocConfigProperties springDocConfigProperties, SpringDocProviders springDocProviders, SpringDocCustomizers springDocCustomizers) {
78+
super(groupedOpenApis, defaultOpenAPIBuilder, requestBuilder, responseBuilder, operationParser, springDocConfigProperties, springDocProviders, springDocCustomizers);
7479
}
7580

7681
/**

springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/api/MultipleOpenApiResource.java

+16-25
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,7 @@
3030
import java.util.stream.Collectors;
3131

3232
import org.springdoc.api.OpenApiResourceNotFoundException;
33-
import org.springdoc.core.customizers.GlobalOpenApiCustomizer;
34-
import org.springdoc.core.customizers.GlobalOperationCustomizer;
3533
import org.springdoc.core.customizers.SpringDocCustomizers;
36-
import org.springdoc.core.filters.GlobalOpenApiMethodFilter;
3734
import org.springdoc.core.models.GroupedOpenApi;
3835
import org.springdoc.core.properties.SpringDocConfigProperties;
3936
import org.springdoc.core.properties.SpringDocConfigProperties.GroupConfig;
@@ -43,19 +40,17 @@
4340
import org.springdoc.core.service.OpenAPIService;
4441
import org.springdoc.core.service.OperationService;
4542

46-
import org.springframework.beans.BeansException;
4743
import org.springframework.beans.factory.InitializingBean;
4844
import org.springframework.beans.factory.ObjectFactory;
49-
import org.springframework.context.ApplicationContext;
50-
import org.springframework.context.ApplicationContextAware;
5145

5246
import static org.springdoc.core.utils.Constants.ACTUATOR_DEFAULT_GROUP;
5347

5448
/**
5549
* The type Multiple open api resource.
50+
*
5651
* @author bnasslahsen
5752
*/
58-
public abstract class MultipleOpenApiResource implements InitializingBean, ApplicationContextAware {
53+
public abstract class MultipleOpenApiResource implements InitializingBean {
5954

6055
/**
6156
* The Grouped open apis.
@@ -93,14 +88,15 @@ public abstract class MultipleOpenApiResource implements InitializingBean, Appli
9388
private final SpringDocProviders springDocProviders;
9489

9590
/**
96-
* The Application context.
91+
* The Grouped open api resources.
9792
*/
98-
protected ApplicationContext applicationContext;
93+
private Map<String, OpenApiResource> groupedOpenApiResources;
94+
9995

10096
/**
101-
* The Grouped open api resources.
97+
* The Spring doc customizers.
10298
*/
103-
private Map<String, OpenApiResource> groupedOpenApiResources;
99+
private final SpringDocCustomizers springDocCustomizers;
104100

105101
/**
106102
* Instantiates a new Multiple open api resource.
@@ -111,11 +107,13 @@ public abstract class MultipleOpenApiResource implements InitializingBean, Appli
111107
* @param responseBuilder the response builder
112108
* @param operationParser the operation parser
113109
* @param springDocConfigProperties the spring doc config properties
110+
* @param springDocProviders the spring doc providers
111+
* @param springDocCustomizers the spring doc customizers
114112
*/
115113
protected MultipleOpenApiResource(List<GroupedOpenApi> groupedOpenApis,
116114
ObjectFactory<OpenAPIService> defaultOpenAPIBuilder, AbstractRequestService requestBuilder,
117115
GenericResponseService responseBuilder, OperationService operationParser,
118-
SpringDocConfigProperties springDocConfigProperties, SpringDocProviders springDocProviders) {
116+
SpringDocConfigProperties springDocConfigProperties, SpringDocProviders springDocProviders, SpringDocCustomizers springDocCustomizers) {
119117

120118
this.groupedOpenApis = groupedOpenApis;
121119
this.defaultOpenAPIBuilder = defaultOpenAPIBuilder;
@@ -124,18 +122,16 @@ protected MultipleOpenApiResource(List<GroupedOpenApi> groupedOpenApis,
124122
this.operationParser = operationParser;
125123
this.springDocConfigProperties = springDocConfigProperties;
126124
this.springDocProviders = springDocProviders;
125+
this.springDocCustomizers = springDocCustomizers;
127126
}
128127

129128
@Override
130129
public void afterPropertiesSet() {
131-
Map<String, GlobalOpenApiCustomizer> globalOpenApiCustomizerMap = applicationContext.getBeansOfType(GlobalOpenApiCustomizer.class);
132-
Map<String, GlobalOperationCustomizer> globalOperationCustomizerMap = applicationContext.getBeansOfType(GlobalOperationCustomizer.class);
133-
Map<String, GlobalOpenApiMethodFilter> globalOpenApiMethodFilterMap = applicationContext.getBeansOfType(GlobalOpenApiMethodFilter.class);
134-
135-
this.groupedOpenApis.forEach(groupedOpenApi -> groupedOpenApi
136-
.addAllOpenApiCustomizer(globalOpenApiCustomizerMap.values())
137-
.addAllOperationCustomizer(globalOperationCustomizerMap.values())
138-
.addAllOpenApiMethodFilter(globalOpenApiMethodFilterMap.values())
130+
this.groupedOpenApis.forEach(groupedOpenApi -> {
131+
springDocCustomizers.getGlobalOpenApiCustomizers().ifPresent(groupedOpenApi::addAllOpenApiCustomizer);
132+
springDocCustomizers.getGlobalOperationCustomizers().ifPresent(groupedOpenApi::addAllOperationCustomizer);
133+
springDocCustomizers.getGlobalOpenApiMethodFilters().ifPresent(groupedOpenApi::addAllOpenApiMethodFilter);
134+
}
139135
);
140136

141137
this.groupedOpenApiResources = groupedOpenApis.stream()
@@ -189,9 +185,4 @@ protected OpenApiResource getOpenApiResourceOrThrow(String group) {
189185
}
190186
return openApiResource;
191187
}
192-
193-
@Override
194-
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
195-
this.applicationContext = applicationContext;
196-
}
197188
}

springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/api/MultipleOpenApiWebFluxResource.java

+7-2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
import com.fasterxml.jackson.core.JsonProcessingException;
3131
import io.swagger.v3.oas.annotations.Operation;
32+
import org.springdoc.core.customizers.SpringDocCustomizers;
3233
import org.springdoc.core.models.GroupedOpenApi;
3334
import org.springdoc.core.properties.SpringDocConfigProperties;
3435
import org.springdoc.core.providers.SpringDocProviders;
@@ -60,16 +61,20 @@ public class MultipleOpenApiWebFluxResource extends MultipleOpenApiResource {
6061

6162
/**
6263
* Instantiates a new Multiple open api resource.
64+
*
6365
* @param groupedOpenApis the grouped open apis
6466
* @param defaultOpenAPIBuilder the default open api builder
6567
* @param requestBuilder the request builder
6668
* @param responseBuilder the response builder
6769
* @param operationParser the operation parser
6870
* @param springDocConfigProperties the spring doc config properties
6971
* @param springDocProviders the spring doc providers
72+
* @param springDocCustomizers the spring doc customizers
7073
*/
71-
public MultipleOpenApiWebFluxResource(List<GroupedOpenApi> groupedOpenApis, ObjectFactory<OpenAPIService> defaultOpenAPIBuilder, AbstractRequestService requestBuilder, GenericResponseService responseBuilder, OperationService operationParser, SpringDocConfigProperties springDocConfigProperties, SpringDocProviders springDocProviders) {
72-
super(groupedOpenApis, defaultOpenAPIBuilder, requestBuilder, responseBuilder, operationParser, springDocConfigProperties, springDocProviders);
74+
public MultipleOpenApiWebFluxResource(List<GroupedOpenApi> groupedOpenApis, ObjectFactory<OpenAPIService> defaultOpenAPIBuilder,
75+
AbstractRequestService requestBuilder, GenericResponseService responseBuilder, OperationService operationParser,
76+
SpringDocConfigProperties springDocConfigProperties, SpringDocProviders springDocProviders, SpringDocCustomizers springDocCustomizers ) {
77+
super(groupedOpenApis, defaultOpenAPIBuilder, requestBuilder, responseBuilder, operationParser, springDocConfigProperties, springDocProviders, springDocCustomizers);
7378
}
7479

7580
/**

springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/configuration/MultipleOpenApiSupportConfiguration.java

+7-4
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
import org.springdoc.core.conditions.MultipleOpenApiSupportCondition;
3030
import org.springdoc.core.configuration.SpringDocConfiguration;
31+
import org.springdoc.core.customizers.SpringDocCustomizers;
3132
import org.springdoc.core.models.GroupedOpenApi;
3233
import org.springdoc.core.properties.SpringDocConfigProperties;
3334
import org.springdoc.core.providers.SpringDocProviders;
@@ -78,6 +79,7 @@ public class MultipleOpenApiSupportConfiguration {
7879
* @param operationParser the operation parser
7980
* @param springDocConfigProperties the spring doc config properties
8081
* @param springDocProviders the spring doc providers
82+
* @param springDocCustomizers the spring doc customizers
8183
* @return the multiple open api resource
8284
*/
8385
@Bean
@@ -88,12 +90,12 @@ MultipleOpenApiWebFluxResource multipleOpenApiResource(List<GroupedOpenApi> grou
8890
ObjectFactory<OpenAPIService> defaultOpenAPIBuilder, AbstractRequestService requestBuilder,
8991
GenericResponseService responseBuilder, OperationService operationParser,
9092
SpringDocConfigProperties springDocConfigProperties,
91-
SpringDocProviders springDocProviders) {
93+
SpringDocProviders springDocProviders, SpringDocCustomizers springDocCustomizers) {
9294
return new MultipleOpenApiWebFluxResource(groupedOpenApis,
9395
defaultOpenAPIBuilder, requestBuilder,
9496
responseBuilder, operationParser,
9597
springDocConfigProperties,
96-
springDocProviders);
98+
springDocProviders, springDocCustomizers);
9799
}
98100

99101
/**
@@ -114,6 +116,7 @@ static class SpringDocWebMvcActuatorDifferentConfiguration {
114116
* @param operationParser the operation parser
115117
* @param springDocConfigProperties the spring doc config properties
116118
* @param springDocProviders the spring doc providers
119+
* @param springDocCustomizers the spring doc customizers
117120
* @return the multiple open api actuator resource
118121
*/
119122
@Bean
@@ -124,10 +127,10 @@ MultipleOpenApiActuatorResource multipleOpenApiActuatorResource(List<GroupedOpen
124127
ObjectFactory<OpenAPIService> defaultOpenAPIBuilder, AbstractRequestService requestBuilder,
125128
GenericResponseService responseBuilder, OperationService operationParser,
126129
SpringDocConfigProperties springDocConfigProperties,
127-
SpringDocProviders springDocProviders) {
130+
SpringDocProviders springDocProviders, SpringDocCustomizers springDocCustomizers) {
128131
return new MultipleOpenApiActuatorResource(groupedOpenApis, defaultOpenAPIBuilder, requestBuilder,
129132
responseBuilder, operationParser,
130-
springDocConfigProperties, springDocProviders);
133+
springDocConfigProperties, springDocProviders, springDocCustomizers);
131134
}
132135
}
133136
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package test.org.springdoc.api.app188;
2+
3+
import io.swagger.v3.oas.models.OpenAPI;
4+
import io.swagger.v3.oas.models.tags.Tag;
5+
import org.springdoc.core.customizers.GlobalOpenApiCustomizer;
6+
import org.springdoc.core.customizers.OpenApiCustomizer;
7+
8+
import org.springframework.core.annotation.Order;
9+
import org.springframework.web.bind.annotation.GetMapping;
10+
import org.springframework.web.bind.annotation.RestController;
11+
12+
13+
public class OrderDemo {
14+
15+
@Order(2)
16+
public static class Customizer2 implements OpenApiCustomizer, GlobalOpenApiCustomizer {
17+
public void customise(OpenAPI openApi) {
18+
openApi.addTagsItem(new Tag().name("2"));
19+
}
20+
}
21+
22+
@Order(3)
23+
public static class Customizer3 implements OpenApiCustomizer, GlobalOpenApiCustomizer {
24+
public void customise(OpenAPI openApi) {
25+
openApi.addTagsItem(new Tag().name("3"));
26+
}
27+
}
28+
29+
@Order(1)
30+
public static class Customizer1 implements OpenApiCustomizer, GlobalOpenApiCustomizer {
31+
public void customise(OpenAPI openApi) {
32+
openApi.addTagsItem(new Tag().name("1"));
33+
}
34+
}
35+
36+
@RestController
37+
public static class MyController {
38+
39+
@GetMapping("/test")
40+
public String testingMethod() {
41+
return "foo";
42+
}
43+
}
44+
45+
}

0 commit comments

Comments
 (0)