Skip to content

Commit ec3f59e

Browse files
committed
Allow AutoCloseable dereferences on original AutoCloseable beans
Closes gh-29480
1 parent 49ee4a4 commit ec3f59e

File tree

2 files changed

+25
-7
lines changed

2 files changed

+25
-7
lines changed

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

+9-7
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ private CachedIntrospectionResults(Class<?> beanClass) throws BeansException {
295295
// Only allow URL attribute introspection, not content resolution
296296
continue;
297297
}
298-
if (pd.getWriteMethod() == null && isInvalidReadOnlyPropertyType(pd.getPropertyType())) {
298+
if (pd.getWriteMethod() == null && isInvalidReadOnlyPropertyType(pd.getPropertyType(), beanClass)) {
299299
// Ignore read-only properties such as ClassLoader - no need to bind to those
300300
continue;
301301
}
@@ -345,7 +345,8 @@ private void introspectInterfaces(Class<?> beanClass, Class<?> currClass, Set<St
345345
// GenericTypeAwarePropertyDescriptor leniently resolves a set* write method
346346
// against a declared read method, so we prefer read method descriptors here.
347347
pd = buildGenericTypeAwarePropertyDescriptor(beanClass, pd);
348-
if (pd.getWriteMethod() == null && isInvalidReadOnlyPropertyType(pd.getPropertyType())) {
348+
if (pd.getWriteMethod() == null &&
349+
isInvalidReadOnlyPropertyType(pd.getPropertyType(), beanClass)) {
349350
// Ignore read-only properties such as ClassLoader - no need to bind to those
350351
continue;
351352
}
@@ -378,7 +379,7 @@ private boolean isPlainAccessor(Method method) {
378379
if (Modifier.isStatic(method.getModifiers()) ||
379380
method.getDeclaringClass() == Object.class || method.getDeclaringClass() == Class.class ||
380381
method.getParameterCount() > 0 || method.getReturnType() == void.class ||
381-
isInvalidReadOnlyPropertyType(method.getReturnType())) {
382+
isInvalidReadOnlyPropertyType(method.getReturnType(), method.getDeclaringClass())) {
382383
return false;
383384
}
384385
try {
@@ -391,10 +392,11 @@ private boolean isPlainAccessor(Method method) {
391392
}
392393
}
393394

394-
private boolean isInvalidReadOnlyPropertyType(@Nullable Class<?> returnType) {
395-
return (returnType != null && (AutoCloseable.class.isAssignableFrom(returnType) ||
396-
ClassLoader.class.isAssignableFrom(returnType) ||
397-
ProtectionDomain.class.isAssignableFrom(returnType)));
395+
private boolean isInvalidReadOnlyPropertyType(@Nullable Class<?> returnType, Class<?> beanClass) {
396+
return (returnType != null && (ClassLoader.class.isAssignableFrom(returnType) ||
397+
ProtectionDomain.class.isAssignableFrom(returnType) ||
398+
(AutoCloseable.class.isAssignableFrom(returnType) &&
399+
!AutoCloseable.class.isAssignableFrom(beanClass))));
398400
}
399401

400402

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

+16
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,10 @@ void propertyDescriptors() throws Exception {
216216
assertThat(accessor.isReadableProperty("inputStream")).isFalse();
217217
assertThat(accessor.isReadableProperty("filename")).isTrue();
218218
assertThat(accessor.isReadableProperty("description")).isTrue();
219+
220+
accessor = createAccessor(new ActiveResource());
221+
222+
assertThat(accessor.isReadableProperty("resource")).isTrue();
219223
}
220224

221225
@Test
@@ -376,6 +380,18 @@ public String getObject() {
376380
}
377381

378382

383+
public static class ActiveResource implements AutoCloseable {
384+
385+
public ActiveResource getResource() {
386+
return this;
387+
}
388+
389+
@Override
390+
public void close() throws Exception {
391+
}
392+
}
393+
394+
379395
public static class GetterWithOptional {
380396

381397
public TestBean value;

0 commit comments

Comments
 (0)