Reinstantiate checks for kotlin-reflect
This commit reinstantiates checks for kotlin-reflect (via static final fields for faster Java code paths and better native code removal) which were removed as part of gh-34275, which did not consider the increasingly popular use cases where kotlin-stdlib is present in the classpath as a transitive dependency in Java applications. Closes gh-35511
This commit is contained in:
parent
7635ac38f6
commit
c79e4e230b
|
@ -88,6 +88,8 @@ public abstract class BeanUtils {
|
||||||
double.class, 0D,
|
double.class, 0D,
|
||||||
char.class, '\0');
|
char.class, '\0');
|
||||||
|
|
||||||
|
private static final boolean KOTLIN_REFLECT_PRESENT = KotlinDetector.isKotlinReflectPresent();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience method to instantiate a class using its no-arg constructor.
|
* Convenience method to instantiate a class using its no-arg constructor.
|
||||||
|
@ -186,7 +188,7 @@ public abstract class BeanUtils {
|
||||||
Assert.notNull(ctor, "Constructor must not be null");
|
Assert.notNull(ctor, "Constructor must not be null");
|
||||||
try {
|
try {
|
||||||
ReflectionUtils.makeAccessible(ctor);
|
ReflectionUtils.makeAccessible(ctor);
|
||||||
if (KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
|
if (KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
|
||||||
return KotlinDelegate.instantiateClass(ctor, args);
|
return KotlinDelegate.instantiateClass(ctor, args);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -279,7 +281,7 @@ public abstract class BeanUtils {
|
||||||
*/
|
*/
|
||||||
public static <T> @Nullable Constructor<T> findPrimaryConstructor(Class<T> clazz) {
|
public static <T> @Nullable Constructor<T> findPrimaryConstructor(Class<T> clazz) {
|
||||||
Assert.notNull(clazz, "Class must not be null");
|
Assert.notNull(clazz, "Class must not be null");
|
||||||
if (KotlinDetector.isKotlinType(clazz)) {
|
if (KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(clazz)) {
|
||||||
return KotlinDelegate.findPrimaryConstructor(clazz);
|
return KotlinDelegate.findPrimaryConstructor(clazz);
|
||||||
}
|
}
|
||||||
if (clazz.isRecord()) {
|
if (clazz.isRecord()) {
|
||||||
|
@ -659,7 +661,7 @@ public abstract class BeanUtils {
|
||||||
ConstructorProperties cp = ctor.getAnnotation(ConstructorProperties.class);
|
ConstructorProperties cp = ctor.getAnnotation(ConstructorProperties.class);
|
||||||
@Nullable String[] paramNames = (cp != null ? cp.value() : parameterNameDiscoverer.getParameterNames(ctor));
|
@Nullable String[] paramNames = (cp != null ? cp.value() : parameterNameDiscoverer.getParameterNames(ctor));
|
||||||
Assert.state(paramNames != null, () -> "Cannot resolve parameter names for constructor " + ctor);
|
Assert.state(paramNames != null, () -> "Cannot resolve parameter names for constructor " + ctor);
|
||||||
int parameterCount = (KotlinDetector.isKotlinReflectPresent() && KotlinDelegate.hasDefaultConstructorMarker(ctor) ?
|
int parameterCount = (KOTLIN_REFLECT_PRESENT && KotlinDelegate.hasDefaultConstructorMarker(ctor) ?
|
||||||
ctor.getParameterCount() - 1 : ctor.getParameterCount());
|
ctor.getParameterCount() - 1 : ctor.getParameterCount());
|
||||||
Assert.state(paramNames.length == parameterCount,
|
Assert.state(paramNames.length == parameterCount,
|
||||||
() -> "Invalid number of parameter names: " + paramNames.length + " for constructor " + ctor);
|
() -> "Invalid number of parameter names: " + paramNames.length + " for constructor " + ctor);
|
||||||
|
|
|
@ -88,6 +88,8 @@ public class InstanceSupplierCodeGenerator {
|
||||||
|
|
||||||
private static final CodeBlock NO_ARGS = CodeBlock.of("");
|
private static final CodeBlock NO_ARGS = CodeBlock.of("");
|
||||||
|
|
||||||
|
private static final boolean KOTLIN_REFLECT_PRESENT = KotlinDetector.isKotlinReflectPresent();
|
||||||
|
|
||||||
|
|
||||||
private final GenerationContext generationContext;
|
private final GenerationContext generationContext;
|
||||||
|
|
||||||
|
@ -161,7 +163,7 @@ public class InstanceSupplierCodeGenerator {
|
||||||
registeredBean.getBeanName(), constructor, registeredBean.getBeanClass());
|
registeredBean.getBeanName(), constructor, registeredBean.getBeanClass());
|
||||||
|
|
||||||
Class<?> publicType = descriptor.publicType();
|
Class<?> publicType = descriptor.publicType();
|
||||||
if (KotlinDetector.isKotlinType(publicType) && KotlinDelegate.hasConstructorWithOptionalParameter(publicType)) {
|
if (KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(publicType) && KotlinDelegate.hasConstructorWithOptionalParameter(publicType)) {
|
||||||
return generateCodeForInaccessibleConstructor(descriptor,
|
return generateCodeForInaccessibleConstructor(descriptor,
|
||||||
hints -> hints.registerType(publicType, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS));
|
hints -> hints.registerType(publicType, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS));
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,8 +35,11 @@ package org.springframework.core;
|
||||||
*/
|
*/
|
||||||
public class DefaultParameterNameDiscoverer extends PrioritizedParameterNameDiscoverer {
|
public class DefaultParameterNameDiscoverer extends PrioritizedParameterNameDiscoverer {
|
||||||
|
|
||||||
|
private static final boolean KOTLIN_REFLECT_PRESENT = KotlinDetector.isKotlinReflectPresent();
|
||||||
|
|
||||||
|
|
||||||
public DefaultParameterNameDiscoverer() {
|
public DefaultParameterNameDiscoverer() {
|
||||||
if (KotlinDetector.isKotlinReflectPresent()) {
|
if (KOTLIN_REFLECT_PRESENT) {
|
||||||
addDiscoverer(new KotlinReflectionParameterNameDiscoverer());
|
addDiscoverer(new KotlinReflectionParameterNameDiscoverer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,8 @@ public class MethodParameter {
|
||||||
|
|
||||||
private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0];
|
private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0];
|
||||||
|
|
||||||
|
private static final boolean KOTLIN_REFLECT_PRESENT = KotlinDetector.isKotlinReflectPresent();
|
||||||
|
|
||||||
|
|
||||||
private final Executable executable;
|
private final Executable executable;
|
||||||
|
|
||||||
|
@ -396,7 +398,8 @@ public class MethodParameter {
|
||||||
*/
|
*/
|
||||||
public boolean isOptional() {
|
public boolean isOptional() {
|
||||||
return (getParameterType() == Optional.class || Nullness.forMethodParameter(this) == Nullness.NULLABLE ||
|
return (getParameterType() == Optional.class || Nullness.forMethodParameter(this) == Nullness.NULLABLE ||
|
||||||
(KotlinDetector.isKotlinType(getContainingClass()) && KotlinDelegate.isOptional(this)));
|
(KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(getContainingClass()) &&
|
||||||
|
KotlinDelegate.isOptional(this)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -484,7 +487,7 @@ public class MethodParameter {
|
||||||
if (this.parameterIndex < 0) {
|
if (this.parameterIndex < 0) {
|
||||||
Method method = getMethod();
|
Method method = getMethod();
|
||||||
paramType = (method != null ?
|
paramType = (method != null ?
|
||||||
(KotlinDetector.isKotlinType(getContainingClass()) ?
|
(KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(getContainingClass()) ?
|
||||||
KotlinDelegate.getGenericReturnType(method) : method.getGenericReturnType()) : void.class);
|
KotlinDelegate.getGenericReturnType(method) : method.getGenericReturnType()) : void.class);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -512,7 +515,7 @@ public class MethodParameter {
|
||||||
if (method == null) {
|
if (method == null) {
|
||||||
return void.class;
|
return void.class;
|
||||||
}
|
}
|
||||||
if (KotlinDetector.isKotlinType(getContainingClass())) {
|
if (KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(getContainingClass())) {
|
||||||
return KotlinDelegate.getReturnType(method);
|
return KotlinDelegate.getReturnType(method);
|
||||||
}
|
}
|
||||||
return method.getReturnType();
|
return method.getReturnType();
|
||||||
|
|
|
@ -77,6 +77,8 @@ public enum Nullness {
|
||||||
*/
|
*/
|
||||||
NON_NULL;
|
NON_NULL;
|
||||||
|
|
||||||
|
private static final boolean KOTLIN_REFLECT_PRESENT = KotlinDetector.isKotlinReflectPresent();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the nullness of the return type for the given method.
|
* Return the nullness of the return type for the given method.
|
||||||
|
@ -84,7 +86,7 @@ public enum Nullness {
|
||||||
* @return the corresponding nullness
|
* @return the corresponding nullness
|
||||||
*/
|
*/
|
||||||
public static Nullness forMethodReturnType(Method method) {
|
public static Nullness forMethodReturnType(Method method) {
|
||||||
if (KotlinDetector.isKotlinType(method.getDeclaringClass())) {
|
if (KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(method.getDeclaringClass())) {
|
||||||
return KotlinDelegate.forMethodReturnType(method);
|
return KotlinDelegate.forMethodReturnType(method);
|
||||||
}
|
}
|
||||||
return (hasNullableAnnotation(method) ? Nullness.NULLABLE :
|
return (hasNullableAnnotation(method) ? Nullness.NULLABLE :
|
||||||
|
@ -97,7 +99,7 @@ public enum Nullness {
|
||||||
* @return the corresponding nullness
|
* @return the corresponding nullness
|
||||||
*/
|
*/
|
||||||
public static Nullness forParameter(Parameter parameter) {
|
public static Nullness forParameter(Parameter parameter) {
|
||||||
if (KotlinDetector.isKotlinType(parameter.getDeclaringExecutable().getDeclaringClass())) {
|
if (KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(parameter.getDeclaringExecutable().getDeclaringClass())) {
|
||||||
// TODO Optimize when kotlin-reflect provide a more direct Parameter to KParameter resolution
|
// TODO Optimize when kotlin-reflect provide a more direct Parameter to KParameter resolution
|
||||||
MethodParameter methodParameter = MethodParameter.forParameter(parameter);
|
MethodParameter methodParameter = MethodParameter.forParameter(parameter);
|
||||||
return KotlinDelegate.forParameter(methodParameter.getExecutable(), methodParameter.getParameterIndex());
|
return KotlinDelegate.forParameter(methodParameter.getExecutable(), methodParameter.getParameterIndex());
|
||||||
|
@ -124,7 +126,7 @@ public enum Nullness {
|
||||||
* @return the corresponding nullness
|
* @return the corresponding nullness
|
||||||
*/
|
*/
|
||||||
public static Nullness forField(Field field) {
|
public static Nullness forField(Field field) {
|
||||||
if (KotlinDetector.isKotlinType(field.getDeclaringClass())) {
|
if (KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(field.getDeclaringClass())) {
|
||||||
return KotlinDelegate.forField(field);
|
return KotlinDelegate.forField(field);
|
||||||
}
|
}
|
||||||
return (hasNullableAnnotation(field) ? Nullness.NULLABLE :
|
return (hasNullableAnnotation(field) ? Nullness.NULLABLE :
|
||||||
|
|
|
@ -360,8 +360,11 @@ public class SpringFactoriesLoader {
|
||||||
*/
|
*/
|
||||||
static final class FactoryInstantiator<T> {
|
static final class FactoryInstantiator<T> {
|
||||||
|
|
||||||
|
private static final boolean KOTLIN_REFLECT_PRESENT = KotlinDetector.isKotlinReflectPresent();
|
||||||
|
|
||||||
private final Constructor<T> constructor;
|
private final Constructor<T> constructor;
|
||||||
|
|
||||||
|
|
||||||
private FactoryInstantiator(Constructor<T> constructor) {
|
private FactoryInstantiator(Constructor<T> constructor) {
|
||||||
ReflectionUtils.makeAccessible(constructor);
|
ReflectionUtils.makeAccessible(constructor);
|
||||||
this.constructor = constructor;
|
this.constructor = constructor;
|
||||||
|
@ -369,7 +372,7 @@ public class SpringFactoriesLoader {
|
||||||
|
|
||||||
T instantiate(@Nullable ArgumentResolver argumentResolver) throws Exception {
|
T instantiate(@Nullable ArgumentResolver argumentResolver) throws Exception {
|
||||||
Object[] args = resolveArgs(argumentResolver);
|
Object[] args = resolveArgs(argumentResolver);
|
||||||
if (KotlinDetector.isKotlinType(this.constructor.getDeclaringClass())) {
|
if (KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(this.constructor.getDeclaringClass())) {
|
||||||
return KotlinDelegate.instantiate(this.constructor, args);
|
return KotlinDelegate.instantiate(this.constructor, args);
|
||||||
}
|
}
|
||||||
return this.constructor.newInstance(args);
|
return this.constructor.newInstance(args);
|
||||||
|
|
|
@ -75,6 +75,9 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
|
||||||
|
|
||||||
private static final Set<Class<?>> BOOLEAN_TYPES = Set.of(Boolean.class, boolean.class);
|
private static final Set<Class<?>> BOOLEAN_TYPES = Set.of(Boolean.class, boolean.class);
|
||||||
|
|
||||||
|
private static final boolean KOTLIN_REFLECT_PRESENT = KotlinDetector.isKotlinReflectPresent();
|
||||||
|
|
||||||
|
|
||||||
private final boolean allowWrite;
|
private final boolean allowWrite;
|
||||||
|
|
||||||
private final Map<PropertyCacheKey, InvokerPair> readerCache = new ConcurrentHashMap<>(64);
|
private final Map<PropertyCacheKey, InvokerPair> readerCache = new ConcurrentHashMap<>(64);
|
||||||
|
@ -558,7 +561,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
|
||||||
|
|
||||||
private static boolean isKotlinProperty(Method method, String methodSuffix) {
|
private static boolean isKotlinProperty(Method method, String methodSuffix) {
|
||||||
Class<?> clazz = method.getDeclaringClass();
|
Class<?> clazz = method.getDeclaringClass();
|
||||||
return KotlinDetector.isKotlinType(clazz) &&
|
return KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(clazz) &&
|
||||||
KotlinDelegate.isKotlinProperty(method, methodSuffix);
|
KotlinDelegate.isKotlinProperty(method, methodSuffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,8 @@ import org.springframework.web.method.support.ModelAndViewContainer;
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractNamedValueMethodArgumentResolver implements HandlerMethodArgumentResolver {
|
public abstract class AbstractNamedValueMethodArgumentResolver implements HandlerMethodArgumentResolver {
|
||||||
|
|
||||||
|
private static final boolean KOTLIN_REFLECT_PRESENT = KotlinDetector.isKotlinReflectPresent();
|
||||||
|
|
||||||
private final @Nullable ConfigurableBeanFactory configurableBeanFactory;
|
private final @Nullable ConfigurableBeanFactory configurableBeanFactory;
|
||||||
|
|
||||||
private final @Nullable BeanExpressionContext expressionContext;
|
private final @Nullable BeanExpressionContext expressionContext;
|
||||||
|
@ -103,7 +105,7 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
|
||||||
|
|
||||||
NamedValueInfo namedValueInfo = getNamedValueInfo(parameter);
|
NamedValueInfo namedValueInfo = getNamedValueInfo(parameter);
|
||||||
MethodParameter nestedParameter = parameter.nestedIfOptional();
|
MethodParameter nestedParameter = parameter.nestedIfOptional();
|
||||||
boolean hasDefaultValue = KotlinDetector.isKotlinType(parameter.getDeclaringClass()) &&
|
boolean hasDefaultValue = KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(parameter.getDeclaringClass()) &&
|
||||||
KotlinDelegate.hasDefaultValue(nestedParameter);
|
KotlinDelegate.hasDefaultValue(nestedParameter);
|
||||||
|
|
||||||
Object resolvedName = resolveEmbeddedValuesAndExpressions(namedValueInfo.name);
|
Object resolvedName = resolveEmbeddedValuesAndExpressions(namedValueInfo.name);
|
||||||
|
|
|
@ -66,6 +66,8 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||||
|
|
||||||
private static final Class<?>[] EMPTY_GROUPS = new Class<?>[0];
|
private static final Class<?>[] EMPTY_GROUPS = new Class<?>[0];
|
||||||
|
|
||||||
|
private static final boolean KOTLIN_REFLECT_PRESENT = KotlinDetector.isKotlinReflectPresent();
|
||||||
|
|
||||||
|
|
||||||
private HandlerMethodArgumentResolverComposite resolvers = new HandlerMethodArgumentResolverComposite();
|
private HandlerMethodArgumentResolverComposite resolvers = new HandlerMethodArgumentResolverComposite();
|
||||||
|
|
||||||
|
@ -247,7 +249,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||||
protected @Nullable Object doInvoke(@Nullable Object... args) throws Exception {
|
protected @Nullable Object doInvoke(@Nullable Object... args) throws Exception {
|
||||||
Method method = getBridgedMethod();
|
Method method = getBridgedMethod();
|
||||||
try {
|
try {
|
||||||
if (KotlinDetector.isKotlinType(method.getDeclaringClass())) {
|
if (KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(method.getDeclaringClass())) {
|
||||||
if (KotlinDetector.isSuspendingFunction(method)) {
|
if (KotlinDetector.isSuspendingFunction(method)) {
|
||||||
return invokeSuspendingFunction(method, getBean(), args);
|
return invokeSuspendingFunction(method, getBean(), args);
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,8 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||||
|
|
||||||
private static final Object NO_ARG_VALUE = new Object();
|
private static final Object NO_ARG_VALUE = new Object();
|
||||||
|
|
||||||
|
private static final boolean KOTLIN_REFLECT_PRESENT = KotlinDetector.isKotlinReflectPresent();
|
||||||
|
|
||||||
|
|
||||||
private final HandlerMethodArgumentResolverComposite resolvers = new HandlerMethodArgumentResolverComposite();
|
private final HandlerMethodArgumentResolverComposite resolvers = new HandlerMethodArgumentResolverComposite();
|
||||||
|
|
||||||
|
@ -197,12 +199,17 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Object value;
|
Object value;
|
||||||
|
boolean isSuspendingFunction;
|
||||||
Method method = getBridgedMethod();
|
Method method = getBridgedMethod();
|
||||||
boolean isSuspendingFunction = KotlinDetector.isSuspendingFunction(method);
|
|
||||||
try {
|
try {
|
||||||
value = (KotlinDetector.isKotlinType(method.getDeclaringClass()) ?
|
if (KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(method.getDeclaringClass())) {
|
||||||
KotlinDelegate.invokeFunction(method, getBean(), args, isSuspendingFunction, exchange) :
|
isSuspendingFunction = KotlinDetector.isSuspendingFunction(method);
|
||||||
method.invoke(getBean(), args));
|
value = KotlinDelegate.invokeFunction(method, getBean(), args, isSuspendingFunction, exchange);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
isSuspendingFunction = false;
|
||||||
|
value = method.invoke(getBean(), args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException ex) {
|
catch (IllegalArgumentException ex) {
|
||||||
assertTargetBean(getBridgedMethod(), getBean(), args);
|
assertTargetBean(getBridgedMethod(), getBean(), args);
|
||||||
|
|
|
@ -69,6 +69,8 @@ import org.springframework.web.server.ServerWebInputException;
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractNamedValueArgumentResolver extends HandlerMethodArgumentResolverSupport {
|
public abstract class AbstractNamedValueArgumentResolver extends HandlerMethodArgumentResolverSupport {
|
||||||
|
|
||||||
|
private static final boolean KOTLIN_REFLECT_PRESENT = KotlinDetector.isKotlinReflectPresent();
|
||||||
|
|
||||||
private final @Nullable ConfigurableBeanFactory configurableBeanFactory;
|
private final @Nullable ConfigurableBeanFactory configurableBeanFactory;
|
||||||
|
|
||||||
private final @Nullable BeanExpressionContext expressionContext;
|
private final @Nullable BeanExpressionContext expressionContext;
|
||||||
|
@ -222,7 +224,7 @@ public abstract class AbstractNamedValueArgumentResolver extends HandlerMethodAr
|
||||||
|
|
||||||
return Mono.fromSupplier(() -> {
|
return Mono.fromSupplier(() -> {
|
||||||
Object value = null;
|
Object value = null;
|
||||||
boolean hasDefaultValue = KotlinDetector.isKotlinType(parameter.getDeclaringClass()) &&
|
boolean hasDefaultValue = KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(parameter.getDeclaringClass()) &&
|
||||||
KotlinDelegate.hasDefaultValue(parameter);
|
KotlinDelegate.hasDefaultValue(parameter);
|
||||||
if (namedValueInfo.defaultValue != null) {
|
if (namedValueInfo.defaultValue != null) {
|
||||||
value = resolveEmbeddedValuesAndExpressions(namedValueInfo.defaultValue);
|
value = resolveEmbeddedValuesAndExpressions(namedValueInfo.defaultValue);
|
||||||
|
|
|
@ -36,6 +36,7 @@ import org.springframework.context.ApplicationContextAware;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.core.KotlinDetector;
|
||||||
import org.springframework.core.convert.converter.Converter;
|
import org.springframework.core.convert.converter.Converter;
|
||||||
import org.springframework.format.Formatter;
|
import org.springframework.format.Formatter;
|
||||||
import org.springframework.format.FormatterRegistry;
|
import org.springframework.format.FormatterRegistry;
|
||||||
|
@ -184,6 +185,8 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
||||||
|
|
||||||
private static final boolean JACKSON_2_PRESENT;
|
private static final boolean JACKSON_2_PRESENT;
|
||||||
|
|
||||||
|
private static final boolean KOTLIN_REFLECT_PRESENT;
|
||||||
|
|
||||||
private static final boolean KOTLIN_SERIALIZATION_PRESENT;
|
private static final boolean KOTLIN_SERIALIZATION_PRESENT;
|
||||||
|
|
||||||
|
|
||||||
|
@ -192,6 +195,7 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
||||||
JACKSON_PRESENT = ClassUtils.isPresent("tools.jackson.databind.ObjectMapper", classLoader);
|
JACKSON_PRESENT = ClassUtils.isPresent("tools.jackson.databind.ObjectMapper", classLoader);
|
||||||
JACKSON_2_PRESENT = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) &&
|
JACKSON_2_PRESENT = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) &&
|
||||||
ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader);
|
ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader);
|
||||||
|
KOTLIN_REFLECT_PRESENT = KotlinDetector.isKotlinReflectPresent();
|
||||||
KOTLIN_SERIALIZATION_PRESENT = ClassUtils.isPresent("kotlinx.serialization.Serializable", classLoader);
|
KOTLIN_SERIALIZATION_PRESENT = ClassUtils.isPresent("kotlinx.serialization.Serializable", classLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -659,7 +663,7 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
||||||
requestBodyAdvices.add(new JsonViewRequestBodyAdvice());
|
requestBodyAdvices.add(new JsonViewRequestBodyAdvice());
|
||||||
responseBodyAdvices.add(new JsonViewResponseBodyAdvice());
|
responseBodyAdvices.add(new JsonViewResponseBodyAdvice());
|
||||||
}
|
}
|
||||||
if (KOTLIN_SERIALIZATION_PRESENT) {
|
if (KOTLIN_REFLECT_PRESENT && KOTLIN_SERIALIZATION_PRESENT) {
|
||||||
requestBodyAdvices.add(new KotlinRequestBodyAdvice());
|
requestBodyAdvices.add(new KotlinRequestBodyAdvice());
|
||||||
responseBodyAdvices.add(new KotlinResponseBodyAdvice());
|
responseBodyAdvices.add(new KotlinResponseBodyAdvice());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue