Skip to content

Commit ea596aa

Browse files
committed
Select most specific advice method in case of override
Closes gh-32865
1 parent 58da30c commit ea596aa

File tree

2 files changed

+25
-17
lines changed

2 files changed

+25
-17
lines changed

spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java

+15-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2023 the original author or authors.
2+
* Copyright 2002-2024 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.
@@ -50,6 +50,7 @@
5050
import org.springframework.core.convert.converter.Converter;
5151
import org.springframework.core.convert.converter.ConvertingComparator;
5252
import org.springframework.lang.Nullable;
53+
import org.springframework.util.ClassUtils;
5354
import org.springframework.util.ReflectionUtils;
5455
import org.springframework.util.ReflectionUtils.MethodFilter;
5556
import org.springframework.util.StringUtils;
@@ -133,17 +134,19 @@ public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstan
133134

134135
List<Advisor> advisors = new ArrayList<>();
135136
for (Method method : getAdvisorMethods(aspectClass)) {
136-
// Prior to Spring Framework 5.2.7, advisors.size() was supplied as the declarationOrderInAspect
137-
// to getAdvisor(...) to represent the "current position" in the declared methods list.
138-
// However, since Java 7 the "current position" is not valid since the JDK no longer
139-
// returns declared methods in the order in which they are declared in the source code.
140-
// Thus, we now hard code the declarationOrderInAspect to 0 for all advice methods
141-
// discovered via reflection in order to support reliable advice ordering across JVM launches.
142-
// Specifically, a value of 0 aligns with the default value used in
143-
// AspectJPrecedenceComparator.getAspectDeclarationOrder(Advisor).
144-
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
145-
if (advisor != null) {
146-
advisors.add(advisor);
137+
if (method.equals(ClassUtils.getMostSpecificMethod(method, aspectClass))) {
138+
// Prior to Spring Framework 5.2.7, advisors.size() was supplied as the declarationOrderInAspect
139+
// to getAdvisor(...) to represent the "current position" in the declared methods list.
140+
// However, since Java 7 the "current position" is not valid since the JDK no longer
141+
// returns declared methods in the order in which they are declared in the source code.
142+
// Thus, we now hard code the declarationOrderInAspect to 0 for all advice methods
143+
// discovered via reflection in order to support reliable advice ordering across JVM launches.
144+
// Specifically, a value of 0 aligns with the default value used in
145+
// AspectJPrecedenceComparator.getAspectDeclarationOrder(Advisor).
146+
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
147+
if (advisor != null) {
148+
advisors.add(advisor);
149+
}
147150
}
148151
}
149152

spring-aop/src/test/java/org/springframework/aop/aspectj/annotation/AbstractAspectJAdvisorFactoryTests.java

+10-5
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,15 @@ abstract class AbstractAspectJAdvisorFactoryTests {
8383
@Test
8484
void rejectsPerCflowAspect() {
8585
assertThatExceptionOfType(AopConfigException.class)
86-
.isThrownBy(() -> getAdvisorFactory().getAdvisors(aspectInstanceFactory(new PerCflowAspect(), "someBean")))
87-
.withMessageContaining("PERCFLOW");
86+
.isThrownBy(() -> getAdvisorFactory().getAdvisors(aspectInstanceFactory(new PerCflowAspect(), "someBean")))
87+
.withMessageContaining("PERCFLOW");
8888
}
8989

9090
@Test
9191
void rejectsPerCflowBelowAspect() {
9292
assertThatExceptionOfType(AopConfigException.class)
93-
.isThrownBy(() -> getAdvisorFactory().getAdvisors(aspectInstanceFactory(new PerCflowBelowAspect(), "someBean")))
94-
.withMessageContaining("PERCFLOWBELOW");
93+
.isThrownBy(() -> getAdvisorFactory().getAdvisors(aspectInstanceFactory(new PerCflowBelowAspect(), "someBean")))
94+
.withMessageContaining("PERCFLOWBELOW");
9595
}
9696

9797
@Test
@@ -770,17 +770,22 @@ public Object doubleAge(ProceedingJoinPoint pjp) throws Throwable {
770770
}
771771
}
772772

773+
773774
@Aspect
774775
static class IncrementingAspect extends DoublingAspect {
775776

777+
@Override
778+
public Object doubleAge(ProceedingJoinPoint pjp) throws Throwable {
779+
return ((int) pjp.proceed()) * 2;
780+
}
781+
776782
@Around("execution(* getAge())")
777783
public int incrementAge(ProceedingJoinPoint pjp) throws Throwable {
778784
return ((int) pjp.proceed()) + 1;
779785
}
780786
}
781787

782788

783-
784789
@Aspect
785790
private static class InvocationTrackingAspect {
786791

0 commit comments

Comments
 (0)