Skip to content

Commit 0641183

Browse files
committed
Consistent ProxyCallbackFilter#equals/hashCode methods
Opaque check in equals instead; no consideration of optimize flag. Closes gh-30616
1 parent 8c7daa8 commit 0641183

File tree

2 files changed

+50
-14
lines changed

2 files changed

+50
-14
lines changed

spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -283,8 +283,8 @@ else if (logger.isDebugEnabled() && !Modifier.isPublic(mod) && !Modifier.isProte
283283

284284
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
285285
// Parameters used for optimization choices...
286-
boolean exposeProxy = this.advised.isExposeProxy();
287286
boolean isFrozen = this.advised.isFrozen();
287+
boolean exposeProxy = this.advised.isExposeProxy();
288288
boolean isStatic = this.advised.getTargetSource().isStatic();
289289

290290
// Choose an "aop" interceptor (used for AOP calls).
@@ -899,9 +899,9 @@ public int accept(Method method) {
899899
// Proxy is not yet available, but that shouldn't matter.
900900
List<?> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
901901
boolean haveAdvice = !chain.isEmpty();
902+
boolean isFrozen = this.advised.isFrozen();
902903
boolean exposeProxy = this.advised.isExposeProxy();
903904
boolean isStatic = this.advised.getTargetSource().isStatic();
904-
boolean isFrozen = this.advised.isFrozen();
905905
if (haveAdvice || !isFrozen) {
906906
// If exposing the proxy, then AOP_PROXY must be used.
907907
if (exposeProxy) {
@@ -970,6 +970,9 @@ public boolean equals(@Nullable Object other) {
970970
if (this.advised.isExposeProxy() != otherAdvised.isExposeProxy()) {
971971
return false;
972972
}
973+
if (this.advised.isOpaque() != otherAdvised.isOpaque()) {
974+
return false;
975+
}
973976
if (this.advised.getTargetSource().isStatic() != otherAdvised.getTargetSource().isStatic()) {
974977
return false;
975978
}
@@ -1016,10 +1019,6 @@ public int hashCode() {
10161019
Advice advice = advisor.getAdvice();
10171020
hashCode = 13 * hashCode + advice.getClass().hashCode();
10181021
}
1019-
hashCode = 13 * hashCode + (this.advised.isFrozen() ? 1 : 0);
1020-
hashCode = 13 * hashCode + (this.advised.isExposeProxy() ? 1 : 0);
1021-
hashCode = 13 * hashCode + (this.advised.isOptimize() ? 1 : 0);
1022-
hashCode = 13 * hashCode + (this.advised.isOpaque() ? 1 : 0);
10231022
return hashCode;
10241023
}
10251024
}

spring-context/src/test/java/org/springframework/aop/framework/CglibProxyTests.java

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -28,13 +28,16 @@
2828
import org.springframework.aop.Pointcut;
2929
import org.springframework.aop.support.AopUtils;
3030
import org.springframework.aop.support.DefaultPointcutAdvisor;
31+
import org.springframework.aop.support.annotation.AnnotationMatchingPointcut;
3132
import org.springframework.aop.testfixture.advice.CountingBeforeAdvice;
3233
import org.springframework.aop.testfixture.interceptor.NopInterceptor;
3334
import org.springframework.beans.testfixture.beans.ITestBean;
3435
import org.springframework.beans.testfixture.beans.TestBean;
3536
import org.springframework.context.ApplicationContext;
3637
import org.springframework.context.ApplicationContextException;
3738
import org.springframework.context.support.ClassPathXmlApplicationContext;
39+
import org.springframework.lang.NonNull;
40+
import org.springframework.lang.Nullable;
3841

3942
import static org.assertj.core.api.Assertions.assertThat;
4043
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -87,8 +90,7 @@ public void testNoTarget() {
8790
AdvisedSupport pc = new AdvisedSupport(ITestBean.class);
8891
pc.addAdvice(new NopInterceptor());
8992
AopProxy aop = createAopProxy(pc);
90-
assertThatExceptionOfType(AopConfigException.class).isThrownBy(
91-
aop::getProxy);
93+
assertThatExceptionOfType(AopConfigException.class).isThrownBy(aop::getProxy);
9294
}
9395

9496
@Test
@@ -136,8 +138,8 @@ public void testProxyCanBeClassNotInterface() {
136138

137139
Object proxy = aop.getProxy();
138140
assertThat(AopUtils.isCglibProxy(proxy)).isTrue();
139-
assertThat(proxy instanceof ITestBean).isTrue();
140-
assertThat(proxy instanceof TestBean).isTrue();
141+
assertThat(proxy).isInstanceOf(ITestBean.class);
142+
assertThat(proxy).isInstanceOf(TestBean.class);
141143

142144
TestBean tb = (TestBean) proxy;
143145
assertThat(tb.getAge()).isEqualTo(32);
@@ -304,6 +306,8 @@ public void testProxyAProxyWithAdditionalInterface() {
304306
CglibAopProxy cglib = new CglibAopProxy(as);
305307

306308
ITestBean proxy1 = (ITestBean) cglib.getProxy();
309+
ITestBean proxy1a = (ITestBean) cglib.getProxy();
310+
assertThat(proxy1a.getClass()).isSameAs(proxy1.getClass());
307311

308312
mockTargetSource.setTarget(proxy1);
309313
as = new AdvisedSupport(new Class<?>[]{});
@@ -312,7 +316,40 @@ public void testProxyAProxyWithAdditionalInterface() {
312316
cglib = new CglibAopProxy(as);
313317

314318
ITestBean proxy2 = (ITestBean) cglib.getProxy();
315-
assertThat(proxy2 instanceof Serializable).isTrue();
319+
assertThat(proxy2).isInstanceOf(Serializable.class);
320+
assertThat(proxy2.getClass()).isNotSameAs(proxy1.getClass());
321+
322+
ITestBean proxy2a = (ITestBean) cglib.getProxy();
323+
assertThat(proxy2a).isInstanceOf(Serializable.class);
324+
assertThat(proxy2a.getClass()).isSameAs(proxy2.getClass());
325+
326+
mockTargetSource.setTarget(proxy1);
327+
as = new AdvisedSupport(new Class<?>[]{});
328+
as.setTargetSource(mockTargetSource);
329+
as.addAdvisor(new DefaultPointcutAdvisor(new AnnotationMatchingPointcut(Nullable.class), new NopInterceptor()));
330+
cglib = new CglibAopProxy(as);
331+
332+
ITestBean proxy3 = (ITestBean) cglib.getProxy();
333+
assertThat(proxy3).isInstanceOf(Serializable.class);
334+
assertThat(proxy3.getClass()).isNotSameAs(proxy2.getClass());
335+
336+
ITestBean proxy3a = (ITestBean) cglib.getProxy();
337+
assertThat(proxy3a).isInstanceOf(Serializable.class);
338+
assertThat(proxy3a.getClass()).isSameAs(proxy3.getClass());
339+
340+
mockTargetSource.setTarget(proxy1);
341+
as = new AdvisedSupport(new Class<?>[]{});
342+
as.setTargetSource(mockTargetSource);
343+
as.addAdvisor(new DefaultPointcutAdvisor(new AnnotationMatchingPointcut(NonNull.class), new NopInterceptor()));
344+
cglib = new CglibAopProxy(as);
345+
346+
ITestBean proxy4 = (ITestBean) cglib.getProxy();
347+
assertThat(proxy4).isInstanceOf(Serializable.class);
348+
assertThat(proxy4.getClass()).isNotSameAs(proxy3.getClass());
349+
350+
ITestBean proxy4a = (ITestBean) cglib.getProxy();
351+
assertThat(proxy4a).isInstanceOf(Serializable.class);
352+
assertThat(proxy4a.getClass()).isSameAs(proxy4.getClass());
316353
}
317354

318355
@Test
@@ -331,7 +368,7 @@ public void testExceptionHandling() {
331368
proxy.doTest();
332369
}
333370
catch (Exception ex) {
334-
assertThat(ex instanceof ApplicationContextException).as("Invalid exception class").isTrue();
371+
assertThat(ex).as("Invalid exception class").isInstanceOf(ApplicationContextException.class);
335372
}
336373

337374
assertThat(proxy.isCatchInvoked()).as("Catch was not invoked").isTrue();

0 commit comments

Comments
 (0)