Browse Source

Allow AutoCloseable dereferences on original AutoCloseable beans

Closes gh-29480
pull/29589/head
Juergen Hoeller 2 years ago
parent
commit
ec3f59e6fe
  1. 16
      spring-beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java
  2. 16
      spring-beans/src/test/java/org/springframework/beans/BeanWrapperTests.java

16
spring-beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java

@ -295,7 +295,7 @@ public final class CachedIntrospectionResults { @@ -295,7 +295,7 @@ public final class CachedIntrospectionResults {
// Only allow URL attribute introspection, not content resolution
continue;
}
if (pd.getWriteMethod() == null && isInvalidReadOnlyPropertyType(pd.getPropertyType())) {
if (pd.getWriteMethod() == null && isInvalidReadOnlyPropertyType(pd.getPropertyType(), beanClass)) {
// Ignore read-only properties such as ClassLoader - no need to bind to those
continue;
}
@ -345,7 +345,8 @@ public final class CachedIntrospectionResults { @@ -345,7 +345,8 @@ public final class CachedIntrospectionResults {
// GenericTypeAwarePropertyDescriptor leniently resolves a set* write method
// against a declared read method, so we prefer read method descriptors here.
pd = buildGenericTypeAwarePropertyDescriptor(beanClass, pd);
if (pd.getWriteMethod() == null && isInvalidReadOnlyPropertyType(pd.getPropertyType())) {
if (pd.getWriteMethod() == null &&
isInvalidReadOnlyPropertyType(pd.getPropertyType(), beanClass)) {
// Ignore read-only properties such as ClassLoader - no need to bind to those
continue;
}
@ -378,7 +379,7 @@ public final class CachedIntrospectionResults { @@ -378,7 +379,7 @@ public final class CachedIntrospectionResults {
if (Modifier.isStatic(method.getModifiers()) ||
method.getDeclaringClass() == Object.class || method.getDeclaringClass() == Class.class ||
method.getParameterCount() > 0 || method.getReturnType() == void.class ||
isInvalidReadOnlyPropertyType(method.getReturnType())) {
isInvalidReadOnlyPropertyType(method.getReturnType(), method.getDeclaringClass())) {
return false;
}
try {
@ -391,10 +392,11 @@ public final class CachedIntrospectionResults { @@ -391,10 +392,11 @@ public final class CachedIntrospectionResults {
}
}
private boolean isInvalidReadOnlyPropertyType(@Nullable Class<?> returnType) {
return (returnType != null && (AutoCloseable.class.isAssignableFrom(returnType) ||
ClassLoader.class.isAssignableFrom(returnType) ||
ProtectionDomain.class.isAssignableFrom(returnType)));
private boolean isInvalidReadOnlyPropertyType(@Nullable Class<?> returnType, Class<?> beanClass) {
return (returnType != null && (ClassLoader.class.isAssignableFrom(returnType) ||
ProtectionDomain.class.isAssignableFrom(returnType) ||
(AutoCloseable.class.isAssignableFrom(returnType) &&
!AutoCloseable.class.isAssignableFrom(beanClass))));
}

16
spring-beans/src/test/java/org/springframework/beans/BeanWrapperTests.java

@ -216,6 +216,10 @@ class BeanWrapperTests extends AbstractPropertyAccessorTests { @@ -216,6 +216,10 @@ class BeanWrapperTests extends AbstractPropertyAccessorTests {
assertThat(accessor.isReadableProperty("inputStream")).isFalse();
assertThat(accessor.isReadableProperty("filename")).isTrue();
assertThat(accessor.isReadableProperty("description")).isTrue();
accessor = createAccessor(new ActiveResource());
assertThat(accessor.isReadableProperty("resource")).isTrue();
}
@Test
@ -376,6 +380,18 @@ class BeanWrapperTests extends AbstractPropertyAccessorTests { @@ -376,6 +380,18 @@ class BeanWrapperTests extends AbstractPropertyAccessorTests {
}
public static class ActiveResource implements AutoCloseable {
public ActiveResource getResource() {
return this;
}
@Override
public void close() throws Exception {
}
}
public static class GetterWithOptional {
public TestBean value;

Loading…
Cancel
Save