Skip to content

Commit cb7b0a3

Browse files
committed
springdoc-openapi-webflux-ui 2.0.0-M7 + spring actuator + spring cloud crashes at startup. Fixes #1904
1 parent 2b44526 commit cb7b0a3

File tree

2 files changed

+106
-72
lines changed

2 files changed

+106
-72
lines changed

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -497,13 +497,12 @@ static class WebConversionServiceConfiguration {
497497
/**
498498
* Web conversion service provider web conversion service provider.
499499
*
500-
* @param genericConversionServiceList the web conversion service optional
501500
* @return the web conversion service provider
502501
*/
503502
@Bean
504503
@Lazy(false)
505-
WebConversionServiceProvider webConversionServiceProvider(Optional<List<GenericConversionService>> genericConversionServiceList) {
506-
return new WebConversionServiceProvider(genericConversionServiceList);
504+
WebConversionServiceProvider webConversionServiceProvider() {
505+
return new WebConversionServiceProvider();
507506
}
508507
}
509508

springdoc-openapi-common/src/main/java/org/springdoc/core/providers/WebConversionServiceProvider.java

Lines changed: 104 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -23,98 +23,133 @@
2323
package org.springdoc.core.providers;
2424

2525
import java.lang.reflect.Field;
26-
import java.util.List;
2726
import java.util.Map;
2827
import java.util.Optional;
2928

3029
import org.apache.commons.lang3.reflect.FieldUtils;
3130
import org.slf4j.Logger;
3231
import org.slf4j.LoggerFactory;
3332

33+
import org.springframework.beans.BeansException;
34+
import org.springframework.beans.factory.InitializingBean;
35+
import org.springframework.context.ApplicationContext;
36+
import org.springframework.context.ApplicationContextAware;
3437
import org.springframework.core.convert.TypeDescriptor;
3538
import org.springframework.core.convert.converter.GenericConverter.ConvertiblePair;
3639
import org.springframework.core.convert.support.GenericConversionService;
3740
import org.springframework.format.support.DefaultFormattingConversionService;
3841
import org.springframework.format.support.FormattingConversionService;
3942
import org.springframework.lang.Nullable;
43+
import org.springframework.util.ClassUtils;
4044

4145
/**
4246
* The type Web conversion service provider.
4347
* @author bnasslashen
4448
*/
45-
public class WebConversionServiceProvider {
46-
47-
/**
48-
* The constant CONVERTERS.
49-
*/
50-
private static final String CONVERTERS = "converters";
51-
52-
/**
53-
* The constant LOGGER.
54-
*/
55-
private static final Logger LOGGER = LoggerFactory.getLogger(WebConversionServiceProvider.class);
56-
57-
/**
58-
* The Formatting conversion service.
59-
*/
60-
private GenericConversionService formattingConversionService;
61-
62-
/**
63-
* Instantiates a new Web conversion service provider.
64-
*
65-
* @param webConversionServiceOptional the web conversion service optional
66-
*/
67-
public WebConversionServiceProvider(Optional<List<GenericConversionService>> webConversionServiceOptional) {
68-
if (webConversionServiceOptional.isPresent()) {
69-
List<GenericConversionService> conversionServiceList = webConversionServiceOptional.get();
70-
for (GenericConversionService genericConversionService : conversionServiceList) {
71-
if (genericConversionService instanceof FormattingConversionService) {
72-
this.formattingConversionService = genericConversionService;
73-
break;
49+
public class WebConversionServiceProvider implements InitializingBean, ApplicationContextAware {
50+
51+
/**
52+
* The constant CONVERTERS.
53+
*/
54+
private static final String CONVERTERS = "converters";
55+
56+
/**
57+
* The constant LOGGER.
58+
*/
59+
private static final Logger LOGGER = LoggerFactory.getLogger(WebConversionServiceProvider.class);
60+
61+
/**
62+
* The Formatting conversion service.
63+
*/
64+
private GenericConversionService formattingConversionService;
65+
66+
67+
/**
68+
* The Application context.
69+
*/
70+
private ApplicationContext applicationContext;
71+
72+
/**
73+
* The constant SERVLET_APPLICATION_CONTEXT_CLASS.
74+
*/
75+
private static final String SERVLET_APPLICATION_CONTEXT_CLASS = "org.springframework.web.context.WebApplicationContext";
76+
77+
/**
78+
* The constant REACTIVE_APPLICATION_CONTEXT_CLASS.
79+
*/
80+
private static final String REACTIVE_APPLICATION_CONTEXT_CLASS = "org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext";
81+
82+
@Override
83+
public void afterPropertiesSet() {
84+
if (isAssignable(SERVLET_APPLICATION_CONTEXT_CLASS, this.applicationContext.getClass())) {
85+
this.formattingConversionService = applicationContext.getBean("mvcConversionService", FormattingConversionService.class);
86+
}
87+
else if (isAssignable(REACTIVE_APPLICATION_CONTEXT_CLASS, this.applicationContext.getClass())) {
88+
this.formattingConversionService = applicationContext.getBean("webFluxConversionService", FormattingConversionService.class);
89+
}
90+
else
91+
formattingConversionService = new DefaultFormattingConversionService();
92+
}
93+
94+
/**
95+
* Attempts to convert {@code source} into the target type as described by {@code targetTypeDescriptor}.
96+
*
97+
* @param source the source
98+
* @param targetTypeDescriptor the target type descriptor
99+
* @return the converted source
100+
*/
101+
@Nullable
102+
public Object convert(@Nullable Object source, TypeDescriptor targetTypeDescriptor) {
103+
return formattingConversionService.convert(source, targetTypeDescriptor);
104+
}
105+
106+
/**
107+
* Gets spring converted type.
108+
*
109+
* @param clazz the clazz
110+
* @return the spring converted type
111+
*/
112+
public Class<?> getSpringConvertedType(Class<?> clazz) {
113+
Class<?> result = clazz;
114+
Field convertersField = FieldUtils.getDeclaredField(GenericConversionService.class, CONVERTERS, true);
115+
if (convertersField != null) {
116+
Object converters;
117+
try {
118+
converters = convertersField.get(formattingConversionService);
119+
convertersField = FieldUtils.getDeclaredField(converters.getClass(), CONVERTERS, true);
120+
Map<ConvertiblePair, Object> springConverters = (Map) convertersField.get(converters);
121+
Optional<ConvertiblePair> convertiblePairOptional = springConverters.keySet().stream().filter(convertiblePair -> convertiblePair.getTargetType().equals(clazz)).findAny();
122+
if (convertiblePairOptional.isPresent()) {
123+
ConvertiblePair convertiblePair = convertiblePairOptional.get();
124+
result = convertiblePair.getSourceType();
125+
}
126+
}
127+
catch (IllegalAccessException e) {
128+
LOGGER.warn(e.getMessage());
74129
}
75130
}
131+
return result;
76132
}
77-
if (formattingConversionService == null)
78-
formattingConversionService = new DefaultFormattingConversionService();
79-
}
80-
81-
/**
82-
* Attempts to convert {@code source} into the target type as described by {@code targetTypeDescriptor}.
83-
*
84-
* @param source the source
85-
* @param targetTypeDescriptor the target type descriptor
86-
* @return the converted source
87-
*/
88-
@Nullable
89-
public Object convert(@Nullable Object source, TypeDescriptor targetTypeDescriptor) {
90-
return formattingConversionService.convert(source, targetTypeDescriptor);
91-
}
92-
93-
/**
94-
* Gets spring converted type.
95-
*
96-
* @param clazz the clazz
97-
* @return the spring converted type
98-
*/
99-
public Class<?> getSpringConvertedType(Class<?> clazz) {
100-
Class<?> result = clazz;
101-
Field convertersField = FieldUtils.getDeclaredField(GenericConversionService.class, CONVERTERS, true);
102-
if(convertersField!=null) {
103-
Object converters;
133+
134+
/**
135+
* Is assignable boolean.
136+
*
137+
* @param target the target
138+
* @param type the type
139+
* @return the boolean
140+
*/
141+
private boolean isAssignable(String target, Class<?> type) {
104142
try {
105-
converters = convertersField.get(formattingConversionService);
106-
convertersField = FieldUtils.getDeclaredField(converters.getClass(), CONVERTERS, true);
107-
Map<ConvertiblePair, Object> springConverters = (Map) convertersField.get(converters);
108-
Optional<ConvertiblePair> convertiblePairOptional = springConverters.keySet().stream().filter(convertiblePair -> convertiblePair.getTargetType().equals(clazz)).findAny();
109-
if (convertiblePairOptional.isPresent()) {
110-
ConvertiblePair convertiblePair = convertiblePairOptional.get();
111-
result = convertiblePair.getSourceType();
112-
}
143+
return ClassUtils.resolveClassName(target, null).isAssignableFrom(type);
113144
}
114-
catch (IllegalAccessException e) {
115-
LOGGER.warn(e.getMessage());
145+
catch (Throwable ex) {
146+
return false;
116147
}
117148
}
118-
return result;
119-
}
149+
150+
@Override
151+
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
152+
this.applicationContext = applicationContext;
153+
}
154+
120155
}

0 commit comments

Comments
 (0)