From cd11219fa7cb50b6dd5958735f1fbeafed73133c Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Fri, 22 Dec 2023 12:27:03 +0100 Subject: [PATCH] Declare proxyMetadataCache as volatile and ProxiedInterfacesCache fields as final See gh-30499 --- .../aop/framework/AdvisedSupport.java | 2 +- .../aop/framework/JdkDynamicAopProxy.java | 28 +++++++++++++------ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java b/spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java index 37d530989f3..c79604c5a57 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java @@ -117,7 +117,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised { * @see JdkDynamicAopProxy#JdkDynamicAopProxy(AdvisedSupport) */ @Nullable - transient Object proxyMetadataCache; + transient volatile Object proxyMetadataCache; /** diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/JdkDynamicAopProxy.java b/spring-aop/src/main/java/org/springframework/aop/framework/JdkDynamicAopProxy.java index 3a1435a09c8..806675ec65b 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/JdkDynamicAopProxy.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/JdkDynamicAopProxy.java @@ -316,31 +316,41 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa */ static final class ProxiedInterfacesCache { - Class[] proxiedInterfaces; + final Class[] proxiedInterfaces; - boolean equalsDefined; + final boolean equalsDefined; - boolean hashCodeDefined; + final boolean hashCodeDefined; ProxiedInterfacesCache(AdvisedSupport config) { this.proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(config, true); // Find any {@link #equals} or {@link #hashCode} method that may be defined - //on the supplied set of interfaces. + // on the supplied set of interfaces. + boolean equalsDefined = false; + boolean hashCodeDefined = false; for (Class proxiedInterface : this.proxiedInterfaces) { Method[] methods = proxiedInterface.getDeclaredMethods(); for (Method method : methods) { if (AopUtils.isEqualsMethod(method)) { - this.equalsDefined = true; + equalsDefined = true; + if (hashCodeDefined) { + break; + } } if (AopUtils.isHashCodeMethod(method)) { - this.hashCodeDefined = true; - } - if (this.equalsDefined && this.hashCodeDefined) { - return; + hashCodeDefined = true; + if (equalsDefined) { + break; + } } } + if (equalsDefined && hashCodeDefined) { + break; + } } + this.equalsDefined = equalsDefined; + this.hashCodeDefined = hashCodeDefined; } }