Skip to content

Commit 2a5d769

Browse files
committed
CglibAopProxy skips method proxy for equals/hashCode/toString override
Issue: SPR-17500
1 parent f5aeb81 commit 2a5d769

File tree

2 files changed

+51
-5
lines changed

2 files changed

+51
-5
lines changed

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -723,17 +723,20 @@ public int hashCode() {
723723
*/
724724
private static class CglibMethodInvocation extends ReflectiveMethodInvocation {
725725

726+
@Nullable
726727
private final MethodProxy methodProxy;
727728

728-
private final boolean publicMethod;
729-
730729
public CglibMethodInvocation(Object proxy, @Nullable Object target, Method method,
731730
Object[] arguments, @Nullable Class<?> targetClass,
732731
List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {
733732

734733
super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
735-
this.methodProxy = methodProxy;
736-
this.publicMethod = Modifier.isPublic(method.getModifiers());
734+
735+
// Only use method proxy for public methods not derived from java.lang.Object
736+
this.methodProxy = (Modifier.isPublic(method.getModifiers()) &&
737+
method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) &&
738+
!AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method) ?
739+
methodProxy : null);
737740
}
738741

739742
/**
@@ -742,7 +745,7 @@ public CglibMethodInvocation(Object proxy, @Nullable Object target, Method metho
742745
*/
743746
@Override
744747
protected Object invokeJoinpoint() throws Throwable {
745-
if (this.publicMethod && getMethod().getDeclaringClass() != Object.class) {
748+
if (this.methodProxy != null) {
746749
return this.methodProxy.invoke(this.target, this.arguments);
747750
}
748751
else {

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

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ protected boolean requiresTarget() {
7474
return true;
7575
}
7676

77+
7778
@Test(expected = IllegalArgumentException.class)
7879
public void testNullConfig() {
7980
new CglibAopProxy(null);
@@ -153,6 +154,20 @@ public void testMethodInvocationDuringConstructor() {
153154
assertEquals("The name property has been overwritten by the constructor", "Rob Harrop", proxy.getName());
154155
}
155156

157+
@Test
158+
public void testToStringInvocation() {
159+
PrivateCglibTestBean bean = new PrivateCglibTestBean();
160+
bean.setName("Rob Harrop");
161+
162+
AdvisedSupport as = new AdvisedSupport();
163+
as.setTarget(bean);
164+
as.addAdvice(new NopInterceptor());
165+
AopProxy aop = new CglibAopProxy(as);
166+
167+
PrivateCglibTestBean proxy = (PrivateCglibTestBean) aop.getProxy();
168+
assertEquals("The name property has been overwritten by the constructor", "Rob Harrop", proxy.toString());
169+
}
170+
156171
@Test
157172
public void testUnadvisedProxyCreationWithCallDuringConstructor() {
158173
CglibTestBean target = new CglibTestBean();
@@ -480,6 +495,29 @@ String getString() {
480495
return this.value;
481496
}
482497
}
498+
499+
500+
private static class PrivateCglibTestBean {
501+
502+
private String name;
503+
504+
public PrivateCglibTestBean() {
505+
setName("Some Default");
506+
}
507+
508+
public void setName(String name) {
509+
this.name = name;
510+
}
511+
512+
public String getName() {
513+
return this.name;
514+
}
515+
516+
@Override
517+
public String toString() {
518+
return this.name;
519+
}
520+
}
483521
}
484522

485523

@@ -498,6 +536,11 @@ public void setName(String name) {
498536
public String getName() {
499537
return this.name;
500538
}
539+
540+
@Override
541+
public String toString() {
542+
return this.name;
543+
}
501544
}
502545

503546

0 commit comments

Comments
 (0)