Browse Source

Do not treat void and Void as simple types in BeanUtils

Prior to this commit, the isSimpleProperty() and isSimpleValueType()
methods in BeanUtils treated void and Void as simple types; however,
doing so does not make sense in this context, since void implies the
lack of a property or value.

This commit addresses this by explicitly excluding void and Void in the
logic in isSimpleValueType().

This commit also simplifies the implementation of
ViewResolutionResultHandler.supports(HandlerResult) to take advantage
of this change.

Closes gh-23573
pull/23837/head
Sam Brannen 6 years ago
parent
commit
d036b5a283
  1. 47
      spring-beans/src/main/java/org/springframework/beans/BeanUtils.java
  2. 71
      spring-beans/src/test/java/org/springframework/beans/BeanUtilsTests.java
  3. 8
      spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java

47
spring-beans/src/main/java/org/springframework/beans/BeanUtils.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 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.
@ -554,35 +554,42 @@ public abstract class BeanUtils { @@ -554,35 +554,42 @@ public abstract class BeanUtils {
}
/**
* Check if the given type represents a "simple" property:
* a primitive, a String or other CharSequence, a Number, a Date,
* a URI, a URL, a Locale, a Class, or a corresponding array.
* Check if the given type represents a "simple" property: a simple value
* type or an array of simple value types.
* <p>See {@link #isSimpleValueType(Class)} for the definition of <em>simple
* value type</em>.
* <p>Used to determine properties to check for a "simple" dependency-check.
* @param clazz the type to check
* @param type the type to check
* @return whether the given type represents a "simple" property
* @see org.springframework.beans.factory.support.RootBeanDefinition#DEPENDENCY_CHECK_SIMPLE
* @see org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#checkDependencies
* @see #isSimpleValueType(Class)
*/
public static boolean isSimpleProperty(Class<?> clazz) {
Assert.notNull(clazz, "Class must not be null");
return isSimpleValueType(clazz) || (clazz.isArray() && isSimpleValueType(clazz.getComponentType()));
public static boolean isSimpleProperty(Class<?> type) {
Assert.notNull(type, "'type' must not be null");
return isSimpleValueType(type) || (type.isArray() && isSimpleValueType(type.getComponentType()));
}
/**
* Check if the given type represents a "simple" value type:
* a primitive, an enum, a String or other CharSequence, a Number, a Date,
* a URI, a URL, a Locale or a Class.
* @param clazz the type to check
* Check if the given type represents a "simple" value type: a primitive or
* primitive wrapper, an enum, a String or other CharSequence, a Number, a
* Date, a URI, a URL, a Locale, or a Class.
* <p>{@code Void} and {@code void} are not considered simple value types.
* @param type the type to check
* @return whether the given type represents a "simple" value type
* @see #isSimpleProperty(Class)
*/
public static boolean isSimpleValueType(Class<?> clazz) {
return (ClassUtils.isPrimitiveOrWrapper(clazz) ||
Enum.class.isAssignableFrom(clazz) ||
CharSequence.class.isAssignableFrom(clazz) ||
Number.class.isAssignableFrom(clazz) ||
Date.class.isAssignableFrom(clazz) ||
URI.class == clazz || URL.class == clazz ||
Locale.class == clazz || Class.class == clazz);
public static boolean isSimpleValueType(Class<?> type) {
return (type != void.class && type != Void.class &&
(ClassUtils.isPrimitiveOrWrapper(type) ||
Enum.class.isAssignableFrom(type) ||
CharSequence.class.isAssignableFrom(type) ||
Number.class.isAssignableFrom(type) ||
Date.class.isAssignableFrom(type) ||
URI.class == type ||
URL.class == type ||
Locale.class == type ||
Class.class == type));
}

71
spring-beans/src/test/java/org/springframework/beans/BeanUtilsTests.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 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.
@ -19,8 +19,14 @@ package org.springframework.beans; @@ -19,8 +19,14 @@ package org.springframework.beans;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URL;
import java.time.DayOfWeek;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.stream.Stream;
import org.junit.Test;
@ -32,7 +38,12 @@ import org.springframework.tests.sample.beans.DerivedTestBean; @@ -32,7 +38,12 @@ import org.springframework.tests.sample.beans.DerivedTestBean;
import org.springframework.tests.sample.beans.ITestBean;
import org.springframework.tests.sample.beans.TestBean;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
* Unit tests for {@link BeanUtils}.
@ -40,6 +51,7 @@ import static org.junit.Assert.*; @@ -40,6 +51,7 @@ import static org.junit.Assert.*;
* @author Juergen Hoeller
* @author Rob Harrop
* @author Chris Beams
* @author Sam Brannen
* @since 19.05.2003
*/
public class BeanUtilsTests {
@ -275,6 +287,60 @@ public class BeanUtilsTests { @@ -275,6 +287,60 @@ public class BeanUtilsTests {
}
}
@Test
public void isSimpleValueType() {
Stream.of(
boolean.class, char.class, byte.class, short.class, int.class,
long.class, float.class, double.class,
Boolean.class, Character.class, Byte.class, Short.class, Integer.class,
Long.class, Float.class, Double.class,
DayOfWeek.class, String.class, Date.class, URI.class, URL.class, Locale.class, Class.class
).forEach(this::assertIsSimpleValueType);
Stream.of(int[].class, Object.class, List.class, void.class, Void.class)
.forEach(this::assertIsNotSimpleValueType);
}
@Test
public void isSimpleProperty() {
Stream.of(
boolean.class, char.class, byte.class, short.class, int.class,
long.class, float.class, double.class,
Boolean.class, Character.class, Byte.class, Short.class, Integer.class,
Long.class, Float.class, Double.class,
DayOfWeek.class, String.class, Date.class, URI.class, URL.class, Locale.class, Class.class,
boolean[].class, Boolean[].class, Date[].class
).forEach(this::assertIsSimpleProperty);
Stream.of(Object.class, List.class, void.class, Void.class)
.forEach(this::assertIsNotSimpleProperty);
}
private void assertIsSimpleValueType(Class<?> type) {
assertTrue("Type [" + type.getName() + "] should be a simple value type", BeanUtils.isSimpleValueType(type));
}
private void assertIsNotSimpleValueType(Class<?> type) {
assertFalse("Type [" + type.getName() + "] should not be a simple value type", BeanUtils.isSimpleValueType(type));
}
private void assertIsSimpleProperty(Class<?> type) {
assertTrue("Type [" + type.getName() + "] should be a simple property", BeanUtils.isSimpleProperty(type));
}
private void assertIsNotSimpleProperty(Class<?> type) {
assertFalse("Type [" + type.getName() + "] should not be a simple property", BeanUtils.isSimpleProperty(type));
}
private void assertSignatureEquals(Method desiredMethod, String signature) {
assertEquals(desiredMethod, BeanUtils.resolveSignature(signature, MethodSignatureBean.class));
}
@ -445,6 +511,7 @@ public class BeanUtilsTests { @@ -445,6 +511,7 @@ public class BeanUtilsTests {
}
}
@SuppressWarnings("unused")
private static class BeanWithSingleNonDefaultConstructor {
private final String name;

8
spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java

@ -160,9 +160,11 @@ public class ViewResolutionResultHandler extends HandlerResultHandlerSupport @@ -160,9 +160,11 @@ public class ViewResolutionResultHandler extends HandlerResultHandlerSupport
type = result.getReturnType().getGeneric().toClass();
}
return (CharSequence.class.isAssignableFrom(type) || Rendering.class.isAssignableFrom(type) ||
Model.class.isAssignableFrom(type) || Map.class.isAssignableFrom(type) ||
Void.class.equals(type) || void.class.equals(type) || View.class.isAssignableFrom(type) ||
return (CharSequence.class.isAssignableFrom(type) ||
Rendering.class.isAssignableFrom(type) ||
Model.class.isAssignableFrom(type) ||
Map.class.isAssignableFrom(type) ||
View.class.isAssignableFrom(type) ||
!BeanUtils.isSimpleProperty(type));
}

Loading…
Cancel
Save